C++, Rust et trading haute fréquence : où la latence déterministe décide du débat
Introduction
Les débats sur le langage de programmation sont généralement tolérés parce que la plupart des systèmes peuvent se permettre un peu de théâtre. Un service est un peu inefficace, une file d'attente devient plus large qu'elle ne le devrait, une politique de nouvelle tentative fait quelque chose de moralement discutable, et tout le monde continue de bouger parce que le produit fonctionne toujours, les revenus atterrissent toujours et le graphique de latence est laid et permet de survivre. Les équipes peuvent passer des semaines à discuter de la pureté parce que le système lui-même est suffisamment poli pour ne pas les gifler immédiatement.
Le trading haute fréquence est moins sentimental. Peu importe quelle langue a gagné Internet ce trimestre, quel discours de conférence avait les diapositives les plus claires ou quelle initiative de réécriture a donné aux gens l'impression que l'avenir était enfin arrivé. Il se soucie de savoir si les données du marché deviennent un état, si l’état devient une décision et si la décision devient un ordre avant que la fenêtre ne se ferme. Dans ce genre d’environnement, les opinions élégantes qui ne peuvent survivre à la mesure sont rapidement et généralement volées sans avertissement.
C'est pourquoi la question de C++ et Rust dans HFT est intéressante. HFT est l'un des rares domaines qui force l'argumentation à se concrétiser dans le comportement réel du système. Soit le chemin chaud conserve sa forme sous pression, soit il ne le conserve pas. Soit la latence de la queue reste disciplinée, soit elle ne le reste pas. Soit la relecture dit la vérité, soit elle ne le fait pas. L’architecture n’y est pas un test de personnalité. Il s'agit d'une facture avec une horloge jointe.
Et HFT est particulièrement honnête quant à la provenance de la facture. Les coûts commencent avant et après la fenêtre d'appariement ou d'exécution. Ils s'accumulent dans l'analyse des flux, la maintenance des livres, la sérialisation, la communication entre cœurs, la gigue sous charge et toutes les petites décisions « probablement bonnes » qui deviennent une humiliation publique une fois que le système est soumis au trafic réel des sites. Le marché a le don cruel de convertir un langage technique vague en pertes exactes.
C'est aussi pourquoi la réponse n'est pas « C++ pour toujours » ou « tout réécrire en Rust parce que la sécurité est une bonne chose et la peur est un modèle commercial ». La réponse la plus honnête est plus précise et donc plus utile. C++ domine toujours les chemins HFT les plus en vogue, car le monde environnant de l'outillage, de la gestion des flux, du contrôle de la mémoire, du profilage et des pratiques adjacentes au matériel reste extrêmement façonné par C++. Rust est véritablement utile autour de ce noyau, et parfois dans des parties soigneusement choisies de celui-ci, mais il n'efface pas le fait fondamental que le trading à faible latence punit les erreurs d'abstraction plus rapidement que la plupart des équipes ne peuvent renommer l'initiative.
La bonne conversation n’est donc pas une question d’identité. Il s’agit des limites du système. Quelles parties de la pile nécessitent un contrôle brutal sur la mémoire, la disposition, les files d'attente, l'affinité et le comportement des câbles ? Quelles parties bénéficient le plus de contraintes d’exactitude plus fortes et de valeurs par défaut plus sûres ? Quelles parties méritent un traitement hybride au lieu d’une pureté tribale ? Ces questions sont bien moins glamour que les sermons linguistiques, mais ce sont aussi des questions qui survivent au contact avec la production et des questions qui permettent aux équipes de coopérer autour de preuves plutôt que de slogans.
Pourquoi HFT donne l'impression qu'une mauvaise philosophie technique coûte cher
HFT est exceptionnellement doué pour dénoncer un mensonge d’ingénierie familier : le mensonge selon lequel un comportement moyen suffit. Dans de nombreux produits ordinaires, un système peut rester respectable tout en cachant un chaos occasionnel derrière le débit, les tentatives ou la patience des utilisateurs. Dans HFT, la latence moyenne est intéressante, mais le comportement de la queue est souvent ce qui vous humilie réellement. Un système qui semble rapide jusqu’à ce qu’il se contracte au mauvais moment n’est pas un système rapide au sens commercial du terme. Il s'agit d'une astuce de confiance avec un point de référence attaché.
C'est pourquoi les ingénieurs HFT deviennent allergiques aux abstractions imprécises. Ils apprennent qu’une allocation supplémentaire sur le hot path n’est pas « juste une allocation ». C'est une source possible de gigue. Un saut de file d'attente n'est pas « juste un saut de file d'attente ». C’est un autre endroit où le temps s’accumule, la coordination se développe et la visibilité se détériore. Une structure hostile au cache devient une taxe permanente sur chaque événement de marché qui traverse le système. Multipliez cela par le volume d'alimentation réel et tout à coup, un choix de conception à partir d'un diaporama devient un élément récurrent du budget qui vous décevra.
La cruauté du domaine est qu’il punit aussi les explications partielles. Une équipe peut identifier une source de latence évidente et ne pas trouver le véritable coupable car la chaîne est cumulative. Une décision d'agencement de la mémoire élargit le profil d'absence de cache. Cela élargit la fenêtre de file d'attente. Cela modifie le comportement du système en cas de trafic en rafale. Cela change l'ordre dans lequel le comportement des branches "rares" apparaît. Puis quelqu'un entre dans l'autopsie et dit que le problème était le « bruit du réseau », qui est un code technique signifiant « nous n'avons pas encore fini de dire la vérité ».
Rust entre dans cette conversation avec une force légitime, car la sécurité de la mémoire est importante, l'exactitude de la concurrence est importante et le code système mérite de meilleures valeurs par défaut que "s'il vous plaît, soyez prudent lorsque vous jonglez avec des couteaux au-dessus d'une fosse". Cette partie est vraie. Mais HFT ne récompense pas la vérité de manière isolée. Il récompense la vérité combinée. La sécurité est importante, oui. Il en va de même pour les gestionnaires de flux matures, les limites ABI stables, les outils de relecture, les itérations basées sur les profils, la culture d'intégration d'échange mature et la capacité d'inspecter exactement ce que fait la machine lorsque le marché n'est pas favorable. C++ arrive toujours avec davantage de cette infrastructure environnante dans la plupart des environnements HFT.
C’est l’une des raisons pour lesquelles les acheteurs et les responsables de l’ingénierie devraient résister aux discours sur la pureté. Un langage peut être excellent dans une dimension étroite et néanmoins être la mauvaise valeur par défaut pour la partie la plus sensible au timing d'une pile si l'écosystème environnant, les outils et l'expérience de l'équipe ne prennent pas en charge le chemin de livraison réel. HFT est l'endroit où les belles vérités locales vont pour apprendre que l'ensemble du chemin compte encore plus. La pile ne se soucie pas du fait qu'une affirmation soit moralement élégante si le système résultant est opérationnellement incohérent.
C’est aussi là que l’écologie de l’équipe compte plus que ce que les gens admettent. Une équipe coopérative dotée d’un système de relecture discipliné, d’un vocabulaire de latence partagé et de bonnes habitudes de profilage ennuyeuses surpassera généralement une équipe plus à la mode qui ne cesse de confondre goût et preuve. HFT récompense une forte culture technique de manière plus fiable qu’elle ne récompense l’énergie migratoire à la mode.
La pile n'est pas une chose, donc le choix de la langue ne doit pas prétendre le contraire
L'une des erreurs les plus stupides dans le travail sérieux sur les systèmes est de parler de « la pile HFT » comme s'il s'agissait d'un organisme technique unique avec un langage préféré. Il échoue à ce test. Il s’agit d’un ensemble de voies comportant des pressions et des coûts d’échec très différents.
Le chemin d’ingestion des données de marché a un seul tempérament. Le chemin de mise à jour du carnet de commandes en a un autre. La logique stratégique peut être numériquement dense mais structurellement étroite. Les contrôles de risque sont souvent sensibles à la latence, mais également à l'exactitude, d'une manière ennuyeuse, adulte et juridiquement conséquente. L’infrastructure de simulation et de relecture peut privilégier le déterminisme et l’introspection plutôt que la vanité brute des nanosecondes. Les outils du plan de contrôle, les aides au déploiement et les surfaces d'opérateur se soucient bien plus de la fiabilité, de la maintenabilité et de l'hygiène de l'intégration que de gagner cinq microsecondes sur un chemin qu'aucun client ne verra jamais.
Il existe également des différences humaines et opérationnelles entre ces couches. Certains parcours sont modifiés quotidiennement par une équipe plus large. Certains sont rarement touchés et uniquement sous surveillance. Certains composants nécessitent une traçabilité agressive car la conformité ou l’audit finira par poser des questions difficiles. Certains n’ont besoin que de performances limitées et d’une excellente relecture. En traitant cela comme une seule décision, les organisations finissent par sur-moderniser les composants calmes ou par sous-gouverner les composants dangereux.
C'est important car c'est souvent là que commence une conversation sensée entre C++ et Rust. C++ reste le plus fort lorsque le chemin est brutalement chaud, soucieux du matériel, lourd en intégration et déjà entouré d'années de pratique opérationnelle native. Rust devient plus attrayant lorsque la voie est toujours importante, mais que la valeur économique de défauts plus forts, d’une propriété plus claire et d’une exposition plus étroite au risque de mémoire dépasse le coût des frictions de l’écosystème.
En pratique, cela conduit souvent à des résultats hybrides. Les chemins de gestion des flux et de passerelle les plus populaires restent dans C++. Les outils de relecture, la validation de configuration, certaines aides côté risque, les utilitaires de normalisation des messages, les outils d'audit ou les composants internes destinés aux opérateurs peuvent être d'excellents candidats Rust. C’est l’âge adulte architectural. Le système est traité comme un ensemble de frontières réelles plutôt que comme un fandom linguistique doté d’un centre de données.
Et c’est là que de nombreuses propositions de réécriture deviennent finalement honnêtes. Une fois qu’une équipe cartographie la pile chemin par chemin, le fantasme d’une réponse universelle unique a tendance à s’effondrer. Cet effondrement est sain. Cela donne à l'organisation la permission d'optimiser les données, la maintenabilité, la confiance opérationnelle et le rythme de livraison, plutôt que le confort émotionnel d'un simple slogan.
Où C++ possède toujours les chemins les plus chauds
C++ conserve sa place dans HFT pour des raisons moins mystiques que ce que les étrangers imaginent parfois. La première raison est le contrôle de la mémoire et de la mise en page. Les chemins chauds HFT se soucient des données qui cohabitent ensemble, du comportement des structures dans le cache, de la façon dont la propriété apparaît sous charge et de la question de savoir si le système peut rester discipliné en matière d'allocation lorsque le marché cesse d'être poli. C++ permet toujours aux ingénieurs d'utiliser ces choix de manière inhabituellement directe, et ce, au sein d'un écosystème qui a déjà passé des décennies à apprendre quels « petits » coûts sont secrètement importants.
La deuxième raison est la densité des outils. C++ dans HFT ne signifie pas seulement un langage. Cela signifie des compilateurs, des désinfectants, des graphiques de flamme, C++, VTune, des harnais de relecture, des adaptateurs d'échange, du folklore de file d'attente, une expertise d'allocation et un vaste corpus d'histoires de guerre de performances accumulées sous la pression financière. Là, les équipes ne partent pas de zéro. Ils héritent d’une culture opérationnelle profonde, et cette culture est importante car HFT récompense bien plus l’itération mesurée que la propreté rhétorique.
La troisième raison est la gravité de l’intégration. Les échanges, les chemins réseau natifs, les outils de capture de paquets, l'optimisation adjacente au noyau, l'infrastructure adjacente à FPGA et l'ensemble de l'écosystème à faible latence sont toujours très à l'aise dans un monde C et C++. Rust peut interagir avec ce monde, et parfois de manière très efficace, mais « peut interagir avec » n'est pas la même chose que « est le chemin de moindre friction à travers l'ensemble du système ». En HFT sérieux, la friction n'est pas un inconvénient émotionnel. Il s’agit à la fois d’une éventuelle taxe de latence, d’une taxe de débogage et d’une taxe de livraison.
Il existe également une raison plus subtile et plus importante à l'ère de l'IA : C++ dispose simplement de plus de mémoire opérationnelle disponible pour ce travail. Les systèmes de codage d'IA, la recherche de code, les exemples publics, les extraits de fournisseurs, le folklore des optimiseurs et les pistes de débogage sont plus denses autour de C++ dans les systèmes à faible latence qu'autour de Rust. Cela ne rend pas C++ plus noble. Cela facilite la collaboration entre les humains et les outils d’IA au sein de bases de code réelles et laides, dont le charme a expiré il y a des années.
Un autre avantage est que de nombreuses équipes HFT ont déjà transformé C++ en mémoire musculaire institutionnelle. Ils savent comment le profiler sous la pression des lieux. Ils savent comment supprimer les allocations des chemins suspects. Ils savent à quoi ressemble « assez vite dans le microbenchmark » quand cela est sur le point de devenir faux en production. Cette connaissance vécue est précieuse sur le plan opérationnel. Une équipe qui sait déjà comment garder C++ honnête ne devrait pas jeter cela à la légère simplement parce qu'un langage plus récent semble plus propre dans l'isolement.
C'est pourquoi C++ reste le plus puissant en tant que système artisanal environnant, et non en tant que syntaxe seule. Une fois que vous avez ajouté des bibliothèques internes, des harnais de test, des outils de capture, des habitudes d'affinité avec les threads, des flux de travail de libération et de diagnostic, vous ne comparez plus un langage à un autre dans le vide. Vous comparez tout un écosystème de livraison à un autre. Dans HFT, les écosystèmes dépassent souvent les idéaux.
Où Rust aide réellement au lieu de faire preuve de moralité
Rust est plus utile lorsqu'il s'agit de résoudre un problème réel plutôt que d'agir comme un accessoire de personnalité pour les diagrammes d'architecture. Dans HFT, les cas d'utilisation les plus puissants de Rust apparaissent souvent autour du noyau chaud plutôt qu'au centre absolu de celui-ci.
Rust est utile pour les composants où les échecs d'exactitude sont coûteux mais où le budget de latence n'est pas mesuré au microscope. Les couches de validation des messages, les outils de configuration et de déploiement, certains chemins de normalisation de protocole, les services de contrôle, les utilitaires d'administration, les analyseurs hors ligne et les outils des opérateurs internes peuvent bénéficier de la préférence du langage pour l'explicite. Le but n’est pas d’avoir l’air moderne. Le but est de réduire la classe d’erreurs stupides, répétitives et structurellement évitables qui détournent l’attention d’un travail plus important.
Rust peut également aider avec des composants presque chauds soigneusement choisis lorsque l'équipe possède l'expertise appropriée et que la limite est honnête. Un analyseur à faible latence, une machine à états limités ou un élément d'infrastructure déterministe peut être un candidat solide pour Rust si l'équipe peut garder le FFI et l'histoire d'allocation sous contrôle et si le fardeau de l'écosystème environnant est compris à l'avance plutôt que découvert à 2h40 du matin lors d'un déploiement dont personne ne voulait.
C'est aussi souvent utile dans le travail autour du travail. Les processeurs de capture, les lecteurs de livres hors ligne, les assistants d'audit, la validation du déploiement ou les infrastructures adjacentes à la stratégie bénéficient d'une propriété plus stricte et d'interfaces plus claires, même lorsqu'ils ne constituent pas le champ de bataille absolu de la nanoseconde. Ces éléments sont importants car ils déterminent la rapidité avec laquelle l’équipe peut diagnostiquer les incidents, reproduire les anomalies et passer en toute sécurité de la suspicion à la compréhension vérifiée.
Mais c’est exactement là que les équipes ont besoin de discipline. Rust n'a pas de valeur lorsqu'il est placé au milieu d'une pile commerciale native en tant que rénovation basée sur la foi. Cela est précieux lorsque la frontière est propre, que le chemin de mesure est évident et que le coût opérationnel de l'intégration est inférieur au gain de sécurité ou de maintenabilité qu'elle crée. Sinon, le projet devient une belle étude de cas sur la façon de consacrer du temps d’ingénierie à déplacer l’incertitude de côté.
Le véritable anti-modèle consiste à utiliser Rust pour masquer l’absence de clarté architecturale. Si l’équipe ne peut pas expliquer où commence la propriété, où la latence est mesurée, où les tampons se croisent et où se produit la récupération en cas de stress, changer le langage ne sauvera pas la conception. Cela ne fera que rendre l'échec plus bilingue.
La frontière compte plus que le sermon
Une erreur courante dans les discussions C++ versus Rust est de supposer que l'utilisation de Rust supprime automatiquement le danger. Ce n’est pas le cas. Cela change là où se situe le danger. Dans HFT, cette question de frontière est particulièrement importante car les chemins chauds se terminent rarement à la limite de la langue. Ils se terminent aux limites du réseau, aux limites de file d'attente, aux limites de planification, aux limites de FFI et aux limites de présentation des données.
Si un composant Rust doit traverser un adaptateur d'échange C++, communiquer avec une file d'attente native, transmettre des données à un moteur de stratégie avec des hypothèses de mise en page strictes ou maintenir un comportement déterministe à travers les transitions de frontières, alors le véritable travail d'ingénierie n'est pas "nous avons utilisé Rust". Le vrai travail réside dans le soin avec lequel la couture a été définie et vérifiée. Un comportement dangereux peut toujours survenir en raison d'une inadéquation ABI, d'une confusion en matière de propriété, de copies cachées, d'erreurs de file d'attente ou de surprises de timing. La langue à elle seule ne constitue pas votre modèle de gouvernance. La limite est.
C’est pourquoi les équipes matures parlent d’un chemin chaud étroit et d’une surface étroite et dangereuse. Ils ne s'appuient pas sur des slogans comme « la sécurité de la mémoire par défaut » pour résoudre ce qui est fondamentalement un problème de conception du système. Les bonnes équipes posent des questions plus laides et donc plus utiles. Où a lieu la copie ? Où est le saut de file d’attente ? De quel côté est propriétaire le tampon ? Quel chemin alloue? Que se passe-t-il pendant la contre-pression ? Qu'est-ce qui est rejouable ? Qu’est-ce qui peut être évalué isolément, et qu’est-ce qui doit l’être de bout en bout, car les victoires locales ont une longue tradition de devenir des déceptions mondiales ?
La clarté des limites crée également un bon sens organisationnel. Une fois les coutures explicites, les équipes peuvent partager les responsabilités sans perdre leur responsabilité. Les ingénieurs de performance savent quoi mesurer. Les gens de la plateforme savent à quoi ne pas toucher avec désinvolture. Les équipes de sécurité et de gestion des risques peuvent raisonner sur les surfaces de défaillance. Les acheteurs et les dirigeants bénéficient d’une lecture technique qui empêche la salle de tourner en rond. Une bonne frontière aide le compilateur et l’entreprise.
C’est l’une des raisons pour lesquelles l’architecture HFT bénéficie d’une posture coopérative et écosystémique plutôt que d’une posture de héros. Les meilleurs systèmes ne sont généralement pas construits par une seule personne prouvant leur pureté. Ils sont construits par un groupe qui s'accorde si minutieusement sur les interfaces, les mesures et la propriété des pannes que le système reste explicable même lorsque le marché cesse d'être favorable.
Cas pratiques à résoudre en premier
Le premier projet le plus intelligent consiste rarement à « réécrire le chemin chaud ». C'est l'équivalent technique de pénétrer dans une maison et de décider que le premier acte utile est de remplacer l'ensemble du squelette avant de vérifier quel tuyau inonde déjà la cuisine.
Le meilleur premier projet est l’un de ceux-ci :
Travail de preuve sur les gestionnaires d'aliments
Si l'équipe se demande si l'analyse, la normalisation, la mise en file d'attente ou le transfert constituent réellement le problème de latence, construisez d'abord le chemin des preuves. Capturez le trafic représentatif, rejouez-le de manière déterministe et forcez le système à admettre où le temps et la gigue entrent réellement dans la chaîne. La plupart des systèmes HFT n’ont pas besoin de plus d’idéologie ici. Ils ont besoin d’un meilleur détecteur de mensonge.
Ce chemin de preuve doit être suffisamment bon pour que la même trace puisse être utilisée par les responsables de la performance, les développeurs et les dirigeants lorsqu'un appel de priorisation strict est nécessaire. Une fois que l’histoire est partagée, la moitié des frictions politiques disparaît parce que la salle ne négocie plus avec des rumeurs.
Nettoyage des passerelles et des limites de risque
De nombreuses piles ne sont pas gâchées par la logique stratégique de base. Ils sont ruinés par le flou des frontières entre le risque, la logique de passerelle et la coordination opérationnelle. Une réécriture ou une restructuration minutieuse à ces coutures peut améliorer la fiabilité et la diagnosticabilité sans le risque commercial de toucher en premier à la boucle absolument la plus chaude.
C’est également là que des garanties linguistiques plus strictes peuvent créer une réelle valeur économique. Si la validation des commandes, la limitation et la messagerie sur les risques deviennent plus faciles à comprendre, l'ensemble du système devient plus calme. Les systèmes calmes sont plus rapides à changer et moins coûteux à gouverner.
Nettoyage du plan de contrôle hybride
Si les outils de l'opérateur, les aides au déploiement, les utilitaires de récupération ou les outils de relecture sont fragiles, Rust peut être un bon candidat. Ces composants façonnent souvent la santé de l’ensemble de l’organisation, même lorsqu’ils ne se situent pas sur le chemin le plus rapide en microsecondes. Des outils plus propres peuvent rendre le système chaud plus calme sans prétendre que chaque binaire du domaine mérite le même langage.
La victoire cachée ici est la santé. De meilleurs outils réduisent la quantité d'archéologie à 2 heures du matin qu'une équipe doit effectuer simplement pour répondre à des questions opérationnelles de base. Cela signifie moins de rituels d’urgence, moins de systèmes fragiles gérés par une seule personne et une meilleure coopération technique à long terme. Dans les organisations d’ingénierie matures, cela compte plus que ce que les gens disent à voix haute.
Laboratoire pratique : Construisez un petit détecteur d'espacement de séquence et rendez-le honnête
Gardons le laboratoire petit et utile. Les systèmes HFT vivent et meurent par discipline de séquence bien avant d'atteindre une logique stratégique glamour. Ce programme de jouets relit un flux semblable à un flux et signale où les lacunes sont apparues.
Le but de l’exercice n’est pas de déployer exactement ce code. Le but est d’enseigner l’habitude de préserver un état déterministe sous pression. La discipline séquentielle est l'un des premiers endroits où un système commercial prouve qu'il respecte les preuves ou prouve qu'il bluffe toujours.
main.cpp
#include <cstdint>
#include <iostream>
#include <string>
#include <vector>
struct Packet {
std::uint64_t seq;
std::string payload;
};
struct Gap {
std::uint64_t expected;
std::uint64_t received;
};
class GapDetector {
public:
void on_packet(const Packet& packet) {
if (!started_) {
expected_ = packet.seq + 1;
started_ = true;
return;
}
if (packet.seq != expected_) {
gaps_.push_back({expected_, packet.seq});
}
expected_ = packet.seq + 1;
}
const std::vector<Gap>& gaps() const {
return gaps_;
}
private:
bool started_ = false;
std::uint64_t expected_ = 0;
std::vector<Gap> gaps_;
};
int main() {
std::vector<Packet> replay{
{1001, "AAPL bid"},
{1002, "AAPL ask"},
{1003, "MSFT bid"},
{1007, "MSFT ask"},
{1008, "NVDA bid"},
{1011, "NVDA ask"}
};
GapDetector detector;
for (const auto& packet : replay) {
detector.on_packet(packet);
}
if (detector.gaps().empty()) {
std::cout << "no gaps\n";
return 0;
}
for (const auto& gap : detector.gaps()) {
std::cout << "gap expected=" << gap.expected
<< " received=" << gap.received << "\n";
}
}
Construire
Sur Linux ou macOS :
g++ -O2 -std=c++20 -o gap_detector main.cpp
./gap_detector
Sur Windows :
cl /O2 /std:c++20 main.cpp
.\main.exe
Résultat attendu :
gap expected=1004 received=1007
gap expected=1009 received=1011
Pourquoi ce petit exercice est important
Parce que cela force à adopter le bon type de réflexion :
- mise à jour d'état déterministe
- séquençage honnête
- rejouer avant la théorie
- comportement limité et mesurable
C'est déjà plus HFT qu'un nombre surprenant de diapositives de conférence.
Si vous souhaitez rendre l'exercice plus réaliste, ajoutez des horodatages, des paquets arrivant tardivement et des réinitialisations de session spécifiques au lieu. Ce qui compte, ce n’est pas de rendre le code plus théâtral. Ce qui compte, c'est de développer le réflexe selon lequel chaque affirmation concernant le flux de données doit être testable, rejouable et suffisamment petite pour être expliquée.
Tâches de test pour les passionnés
- Portez le même détecteur sur Rust et comparez la clarté des limites, les frictions de dépendance et l'ajustement avec vos outils existants.
- Prolongez la relecture afin que les paquets manquants puissent arriver plus tard dans le désordre, puis décidez si le détecteur doit les mettre en mémoire tampon, les rejeter ou les signaler.
- Ajoutez du timing et mesurez la différence entre une relecture vectorielle et une relecture basée sur un tampon en anneau.
- Introduisez une allocation inutile sur le chemin chaud et mesurez la rapidité avec laquelle une « petite » décision commence à contaminer le résultat.
- Ajoutez une branche de journalisation à l'intérieur de
on_packetet observez à quelle vitesse l'observabilité devient un sabotage lorsqu'elle est placée avec négligence.
Résumé
La vraie conversation C++ et Rust dans HFT ne porte pas sur quelle langue mérite la mythologie la plus agréable. Il s’agit de savoir quelles parties du système nécessitent un contrôle direct, quelles parties bénéficient de paramètres par défaut plus forts et quelles limites peuvent être rendues suffisamment honnêtes pour prendre en charge la conception hybride sans illusion.
C++ domine toujours les chemins HFT les plus en vogue, car le domaine récompense le contrôle de la disposition de la mémoire, de la file d'attente, du comportement des câbles, du profilage, de la relecture et de l'intégration avec un écosystème mature à faible latence. Rust est utile lorsque l'exactitude, l'explicitation et la maintenabilité créent plus de valeur que les coûts de friction supplémentaires de l'écosystème. Les deux peuvent appartenir à un stack sérieux. La démarche des adultes consiste à décider où et à laisser les preuves plutôt que le fandom linguistique compter les points.
Les équipes qui réussissent font quelque chose de très peu glamour et de très efficace. Ils arrêtent de se demander quelle langue les sauvera et commencent à se demander quelle frontière mérite quel type de discipline. Ce changement semble modeste, mais c’est la différence entre l’architecture en tant que marque et l’architecture en tant que vérité opérationnelle. Dans HFT, la vérité vieillit généralement mieux.
Références
- Spécification NASDAQ TotalView-ITCH : ITCH
- FIX Normes de la communauté commerciale : FIX
- Documentation DPDK : https://doc.dpdk.org/guides/
- Documentation d'horodatage Linux : Linux
- Brendan Gregg sur les graphiques de flamme : https://www.brendangregg.com/flamegraphs.html
- Le livre de performances Rust : Rust