How-To Guides

Zoomer : Optimiser l'E/S et le réseau Linux pour le trading haute fréquence

Le trading haute fréquence (HFT) opère à l'échelle de la microseconde. À cette vitesse, les surcoûts standards du système d'exploitation ne sont plus tolérables ; ils sont fatals. Pour atteindre une faible latence constante, les développeurs doivent aller au-delà des configurations Linux « prêtes à l'emploi » et plonger dans les entrailles du noyau. Ce guide explore les optimisations critiques du planificateur E/S et de la pile réseau pour vous assurer que votre application de trading ne laisse aucune pierre sur la table dans la quête de la vitesse.

Sélection et réglage du planificateur E/S

Le noyau Linux propose plusieurs planificateurs E/S, chacun avec des compromis différents entre le débit et la latence. Pour le HFT, où un accès prévisible et à faible latence au stockage ou à la mémoire partagée est crucial, les planificateurs Deadline ou Noop (ou MQ-Deadline) sont généralement préférés par rapport aux CFQ ou BFQ par défaut.

Pourquoi Deadline ? Il garantit que les requêtes E/S sont traitées dans un délai spécifié, ce qui est essentiel pour la journalisation de données sensibles au temps ou la persistance du carnet d'ordres. Noop est idéal pour les disques à semi-conducteurs (SSD) ou les dispositifs NVM Express (NVMe) où le matériel gère sa propre mise en file et son ordonnancement.

# Vérifier le planificateur E/S actuel pour /dev/sda
cat /sys/block/sda/queue/scheduler

# Définir le planificateur deadline (nécessite les droits root)
echo deadline > /sys/block/sda/queue/scheduler

# Augmenter la profondeur de la file E/S pour NVMe (exemple)
echo 256 > /sys/block/nvme0n1/queue/nr_requests

Optimisation de la pile réseau : Contourner le noyau

La pile réseau Linux traditionnelle implique plusieurs changements de contexte et copies de mémoire, qui sont des sources significatives de latence. Pour le HFT, deux stratégies principales sont employées : le réglage des sockets TCP et le réseau en espace utilisateur (comme DPDK ou FRR).

1. Réglage de la pile du noyau

Avant d'envisager des solutions en espace utilisateur, optimisez la pile du noyau. Les paramètres clés incluent la désactivation de l'algorithme de Nagle, l'ajustement des tailles de tampon TCP et la réduction des longueurs de file.

# Désactiver l'algorithme de Nagle (par socket)
setsockopt(sockfd, SOL_TCP, TCP_NODELAY, &flag, sizeof flag);

# Réglage TCP système (exemple sysctl)
# Augmenter les tampons d'envoi/réception
net.core.wmem_max = 16777216
net.core.rmem_max = 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216

# Réduire la taille du tampon de réordonnancement TCP
net.ipv4.tcp_adv_win_scale = 1

2. Affinité des interruptions et prise en compte de NUMA

Les cartes d'interface réseau (NIC) génèrent des interruptions gérées par des cœurs CPU spécifiques. Dans les systèmes multi-sockets ou NUMA, si l'interruption est gérée sur un cœur éloigné de la mémoire de l'application, des pics de latence se produisent.

Lier les interruptions NIC aux CPU locaux :

# Identifier le numéro d'IRQ pour eth0
grep eth0 /proc/interrupts

# Lier l'IRQ 20 au CPU 0 (à ajuster selon votre topologie)
echo 1 > /proc/irq/20/smp_affinity

Exemple pratique : Configuration d'un socket à faible latence

Voici un extrait en C démontrant un socket configuré pour un surcoût minimal :


#include <sys/socket.h>
#include <netinet/tcp.h>

int create_optimized_socket() {
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        perror("socket");
        return -1;
    }

    int flag = 1;
    // Désactiver Nagle
    setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof flag);

    // Définir la taille du tampon de réception
    int rcvbuf = 4 * 1024 * 1024; // 4 Mo
    setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof rcvbuf);

    // Activer keepalive pour la détection d'inactivité
    setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, &flag, sizeof flag);

    return sockfd;
}

Conclusion

L'optimisation pour le HFT ne consiste pas à trouver un réglage magique unique. C'est une approche holistique impliquant la sélection du planificateur E/S, le réglage des paramètres du noyau et une gestion soignée de l'affinité CPU et de la topologie NUMA. Mesurez toujours l'impact de chaque modification en utilisant des outils précis comme perf et des sondes de latence personnalisées. N'oubliez pas : en HFT, chaque nanoseconde compte, et votre configuration système doit refléter cette obsession de la précision.

Share: