C++, Rust e trading ad alta frequenza: dove la latenza deterministica decide l'argomento
Introduzione
I dibattiti sul linguaggio di programmazione sono generalmente tollerati perché la maggior parte dei sistemi può permettersi un po' di teatro. Un servizio è un po' inefficiente, una coda diventa più ampia del dovuto, una politica di riprova fa qualcosa di moralmente discutibile e tutti continuano a muoversi perché il prodotto funziona ancora, le entrate arrivano ancora e il grafico della latenza è brutto in modo sopravvissuto. I team possono passare settimane a discutere sulla purezza perché il sistema stesso è abbastanza educato da non schiaffeggiarli immediatamente.
Il trading ad alta frequenza è meno sentimentale. Non importa quale lingua abbia vinto su Internet in questo trimestre, quale conferenza abbia avuto le diapositive più pulite o quale iniziativa di riscrittura abbia fatto sentire le persone come se il futuro fosse finalmente arrivato. Gli importa se i dati di mercato diventano stato, lo stato diventa una decisione e la decisione diventa un ordine prima che la finestra si chiuda. In questo tipo di ambiente, le opinioni eleganti che non possono sopravvivere alla misurazione vengono rapinate rapidamente e di solito senza preavviso.
Ecco perché la questione di C++ e Rust in HFT è interessante. Non perché una lingua sia sacra e l'altra sia fraudolenta, ma perché HFT è uno dei rari ambiti che costringe l'intera argomentazione a tradursi in un comportamento effettivo del sistema. Il percorso caldo mantiene la sua forma sotto pressione oppure no. La latenza della coda rimane disciplinata oppure no. Replay o dice la verità oppure no. Lì l’architettura non è un test della personalità. È una fattura con un orologio allegato.
E HFT è insolitamente onesto riguardo alla provenienza del conto. Non si tratta solo della finestra di corrispondenza o di esecuzione stessa. I costi si accumulano nell’analisi dei feed, nella manutenzione dei libri, nella serializzazione, nella comunicazione cross-core, nel jitter sotto carico e in tutte le piccole decisioni “probabilmente buone” che diventano umiliazione pubblica una volta che il sistema è sottoposto al traffico della sede reale. Il mercato ha il dono crudele di convertire un vago linguaggio ingegneristico in perdite esatte.
Questo è anche il motivo per cui la risposta non è "C++ per sempre" o "riscrivi tutto in Rust perché la sicurezza è una cosa positiva e la paura è un modello di business". La risposta più onesta è più ristretta e quindi più utile. C++ domina ancora i percorsi HFT più caldi perché il mondo circostante di strumenti, gestione dei feed, controllo della memoria, profilazione e pratiche adiacenti all'hardware rimane estremamente modellato su C++. Rust è veramente utile attorno a quel nucleo, e talvolta all'interno di parti di esso scelte con cura, ma non cancella il fatto fondamentale che il trading a bassa latenza punisce gli errori di astrazione più velocemente di quanto la maggior parte dei team riesca a rinominare l'iniziativa.
Quindi la conversazione giusta non riguarda l’identità. Riguarda i confini del sistema. Quali parti dello stack necessitano di un controllo brutale su memoria, layout, code, affinità e comportamento dei cavi? Quali parti traggono maggiori benefici da vincoli di correttezza più forti e da valori predefiniti più sicuri? Quali parti meritano un trattamento ibrido invece della purezza tribale? Queste domande sono molto meno affascinanti dei sermoni linguistici, ma sono anche le domande che sopravvivono al contatto con la produzione e le domande che consentono IA team di cooperare attorno alle prove invece che agli slogan.
Perché HFT fa sembrare costosa la cattiva filosofia tecnica
HFT è insolitamente bravo a smascherare una bugia ingegneristica familiare: la bugia secondo cui il comportamento medio è sufficiente. In molti prodotti comuni, un sistema può rimanere rispettabile nascondendo il caos occasionale dietro il throughput, i nuovi tentativi o la pazienza dell'utente. In HFT, la latenza media è interessante, ma il comportamento della coda è spesso la parte che in realtà ti umilia. Un sistema che sembra veloce finché non scatta nel momento sbagliato non è un sistema veloce in alcun senso commercialmente significativo. È un trucco di fiducia con un benchmark allegato.
Ecco perché gli ingegneri di HFT diventano allergici alle astrazioni imprecise. Imparano che un'allocazione extra sul percorso caldo non è "solo un'allocazione". È una possibile fonte di jitter. Un salto in coda non è "solo un salto in coda". È un altro luogo in cui il tempo viene immagazzinato, la coordinazione si espande e la visibilità peggiora. Una struttura ostile alla cache non è solo un difetto estetico. È una tassa continua su ogni evento di mercato che attraversa il sistema. Moltiplicalo per il volume reale del feed e all'improvviso una scelta di design da una presentazione diventa una voce ricorrente nel budget per la delusione.
La crudeltà del dominio è che punisce anche le spiegazioni parziali. Un team può identificare un'ovvia fonte di latenza e tuttavia non individuare il vero colpevole perché la catena è cumulativa. Una decisione sul layout della memoria amplia il profilo di cache miss. Ciò amplia la finestra di coda. Ciò cambia il modo in cui il sistema si comporta in caso di traffico intenso. Ciò cambia l'ordine in cui viene visualizzato il comportamento del ramo "raro". Poi qualcuno arriva all'autopsia e dice che il problema era "rumore di rete", che in codice tecnico significa "non abbiamo ancora finito di dire la verità".
Rust entra in questa conversazione con forza legittima perché la sicurezza della memoria è importante, la correttezza della concorrenza è importante e il codice di sistema merita valori predefiniti migliori di "fai attenzione mentre giochi con i coltelli su una fossa". Quella parte è vera. Ma HFT non premia la verità isolatamente. Premia la verità combinata. La sicurezza conta, sì. Lo stesso vale per i gestori di feed maturi, i confini ABI stabili, gli strumenti di riproduzione, l'iterazione basata sui profili, la cultura matura dell'integrazione degli scambi e la capacità di ispezionare esattamente cosa sta facendo la macchina quando il mercato è scortese. C++ arriva ancora con più di quell'infrastruttura circostante nella maggior parte degli ambienti HFT.
Questo è uno dei motivi per cui gli acquirenti e i leader dell’ingegneria dovrebbero opporsi alle narrazioni sulla purezza. Un linguaggio può essere eccellente in una dimensione ristretta ed essere comunque l'impostazione predefinita sbagliata per la parte di uno stack più sensibile IA tempi se l'ecosistema circostante, gli strumenti e l'esperienza del team non supportano il percorso di consegna effettivo. HFT è il luogo in cui vanno le adorabili verità locali per apprendere che l'intero percorso conta ancora di più. Allo stack non interessa che un'affermazione sia moralmente elegante se il sistema risultante è operativamente incoerente.
È anche il luogo in cui l’ecologia del team conta più di quanto la gente ammetta. Un team cooperativo con un sistema di replay disciplinato, un vocabolario di latenza condiviso e abitudini di profilazione noiosamente buone di solito avrà prestazioni migliori di un team più alla moda che continua a confondere il gusto per le prove. HFT premia una forte cultura tecnica in modo più affidabile di quanto premi l'energia migratoria alla moda.
Lo stack non è una cosa, quindi la scelta della lingua non dovrebbe fingere il contrario
Uno degli errori più stupidi nel lavoro serio sui sistemi è parlare dello "stack HFT" come se fosse un unico organismo tecnico con un linguaggio preferito. Non lo è. Si tratta di un insieme di percorsi con pressioni e costi di fallimento molto diversi.
Il percorso di acquisizione dei dati di mercato ha un temperamento. Il percorso di aggiornamento del portafoglio ordini ne ha un altro. La logica della strategia può essere numericamente densa ma strutturalmente ristretta. I controlli del rischio sono spesso sensibili alla latenza ma anche alla correttezza in un modo noioso, adulto e giuridicamente consequenziale. Le infrastrutture di simulazione e riproduzione possono privilegiare il determinismo e l’introspezione rispetto alla pura vanità dei nanosecondi. Gli strumenti del piano di controllo, gli aiutanti per l'implementazione e le superfici operatore si preoccupano dell'affidabilità, della manutenibilità e dell'igiene dell'integrazione molto più di quanto si preoccupino di eliminare cinque microsecondi da un percorso che nessun cliente vedrà mai.
Ci sono anche differenze umane e operative tra questi livelli. Alcuni percorsi vengono modificati quotidianamente da un team più ampio. Alcuni vengono toccati raramente e solo sotto supervisione. Alcuni componenti necessitano di una tracciabilità aggressiva perché la conformità o l'audit finiranno per porre domande difficili. Alcuni necessitano solo di prestazioni limitate e di un'eccellente riproduzione. Trattarle come un’unica decisione è il modo in cui le organizzazioni finiscono per modernizzare eccessivamente le componenti tranquille o sottogovernare quelle pericolose.
Questo è importante perché è spesso il punto in cui inizia una conversazione sensata tra C++ e Rust. C++ rimane più forte quando il percorso è brutalmente caldo, attento all'hardware, ricco di integrazione e già circondato da anni di pratica operativa nativa. Rust diventa più attraente quando il percorso è ancora importante, ma il valore economico di default più forti, proprietà più chiara e minore esposizione al rischio di memoria supera il costo dell’attrito dell’ecosistema.
In pratica, ciò porta spesso a risultati ibridi. I percorsi di gestione dei feed e gateway più importanti rimangono in C++. Strumenti di riproduzione, convalida della configurazione, alcuni aiutanti dal lato del rischio, utilità di normalizzazione dei messaggi, strumenti di controllo o componenti interni rivolti all'operatore possono essere eccellenti candidati Rust. Questa non è indecisione. È l’età adulta architettonica. Il sistema viene trattato come un insieme di confini reali piuttosto che come un fandom linguistico con un data center.
Ed è qui che molte proposte di riscrittura diventano finalmente oneste. Una volta che una squadra mappa lo stack percorso per percorso, la fantasia di un’unica risposta universale tende a crollare. Questo crollo è salutare. Dà all'organizzazione il permesso di ottimizzare per prove, manutenibilità, fiducia operativa e ritmo di consegna invece che per il conforto emotivo di avere un semplice slogan.
Dove C++ possiede ancora i percorsi più caldi
C++ mantiene il suo posto in HFT per ragioni meno mistiche di quanto talvolta gli estranei immaginano. Il primo motivo è il controllo della memoria e del layout. HFT i percorsi caldi si preoccupano di quali dati convivono, di come si comportano le strutture nella cache, di come la proprietà appare sotto carico e se il sistema può rimanere disciplinato dall'allocazione quando il mercato smette di essere educato. C++ offre ancora agli ingegneri un potere insolitamente diretto su tali scelte, e lo fa all'interno di un ecosistema che ha già trascorso decenni a imparare quali costi "piccoli" sono segretamente grandi.
Il secondo motivo è la densità degli utensili. C++ in HFT non significa solo un linguaggio. Significa compilatori, disinfettanti, grafici delle fiamme, C++, VTune, cablaggi di riproduzione, adattatori di scambio, folklore sulle code, esperienza nell'allocazione e un vasto corpus di storie di guerre sulle prestazioni accumulate sotto pressione finanziaria. Lì le squadre non partono da zero. Ereditano una profonda cultura operativa, e quella cultura è importante perché HFT premia l'iterazione misurata molto più della pulizia retorica.
La terza ragione è la gravità dell’integrazione. Gli scambi, i percorsi di rete nativi, gli strumenti di acquisizione dei pacchetti, l'ottimizzazione del kernel adiacente, l'infrastruttura FPGA adiacente e l'intero ecosistema a bassa latenza sono ancora molto a loro agio in un mondo C e C++. Rust può interagire con quel mondo, e talvolta in modo molto efficace, ma "può interagire con" non è la stessa cosa di "è il percorso di minor attrito attraverso l'intero sistema". Nel HFT serio, l'attrito non è un disagio emotivo. Si tratta di una possibile tassa di latenza, una tassa di debug e una tassa di consegna allo stesso tempo.
C'è anche una ragione più sottile che conta di più nell'era IA: C++ ha semplicemente più memoria operativa disponibile per questo lavoro. I sistemi di codifica IA, la ricerca del codice, gli esempi pubblici, gli snippet dei fornitori, il folklore degli ottimizzatori e le tracce di debug sono più densi intorno a C++ nei sistemi a bassa latenza che intorno a Rust. Ciò non rende C++ più nobile. Rende più facile per gli esseri umani e gli strumenti IA collaborare all'interno di brutte basi di codice reali il cui fascino è scaduto anni fa.
Un altro vantaggio è che molti team HFT hanno già trasformato C++ in una memoria muscolare istituzionale. Sanno come profilarlo sotto la pressione della sede. Sanno come sottrarre gli stanziamenti a percorsi sospetti. Sanno cosa significa "abbastanza veloce nel microbenchmark" quando sta per diventare falso nella produzione. Quella conoscenza vissuta non è romantica, ma è operativamente preziosa. Un team che sa già come mantenere C++ onesto non dovrebbe buttarlo via alla leggera solo perché un linguaggio più nuovo sembra più pulito da solo.
Questo è il motivo per cui C++ rimane più forte non solo come sintassi, ma come sistema artigianale circostante. Una volta aggiunte librerie interne, test di cablaggio, strumenti di acquisizione, abitudini di affinità dei thread, rilascio di muscoli e flussi di lavoro di diagnosi, non si confronta più una lingua con un'altra nel vuoto. Stai confrontando un intero ecosistema di consegna con un altro. In HFT, gli ecosistemi spesso battono gli ideali.
Dove Rust aiuta effettivamente invece di adempiere alla moralità
Rust aiuta di più quando risolve un problema reale piuttosto che agire come un accessorio di personalità per i diagrammi architettonici. In HFT, i casi d'uso più forti di Rust spesso appaiono attorno al nucleo caldo piuttosto che al centro assoluto di esso.
Rust è utile per i componenti in cui i difetti di correttezza sono costosi ma il budget di latenza non viene misurato al microscopio. I livelli di convalida dei messaggi, gli strumenti di configurazione e distribuzione, alcuni percorsi di normalizzazione del protocollo, i servizi di controllo, le utilità amministrative, gli analizzatori offline e gli strumenti degli operatori interni possono trarre vantaggio dalla preferenza del linguaggio verso l’esplicitezza. Il punto non è sembrare moderno. Il punto è ridurre la classe di errori stupidi, ripetitivi e strutturalmente evitabili che distolgono l’attenzione da lavori più importanti.
Rust può anche aiutare nella scelta accurata di componenti quasi caldi quando il team ha la giusta esperienza e il confine è onesto. Un parser a bassa latenza, una macchina a stati limitati o un pezzo di infrastruttura deterministica possono essere un solido candidato Rust se il team riesce a tenere sotto controllo la FFI e la storia dell'allocazione e se il carico dell'ecosistema circostante viene compreso in anticipo anziché scoperto alle 2:40 del mattino durante un'implementazione che nessuno voleva.
Spesso è anche utile nel lavoro attorno al lavoro. I processori di acquisizione, i riproduttori di libri offline, gli assistenti di controllo, la convalida dell'implementazione o l'infrastruttura adiacente alla strategia beneficiano di una proprietà più rigorosa e di interfacce più chiare anche quando non sono il campo di battaglia assoluto dei nanosecondi. Questi elementi sono importanti perché determinano la velocità con cui il team può diagnosticare gli incidenti, riprodurre le anomalie e passare in sicurezza dal sospetto alla comprensione verificata.
Ma è proprio qui che le squadre hanno bisogno di disciplina. Rust non ha valore quando viene lasciato cadere nel mezzo di uno stack di scambio nativo come rinnovamento basato sulla fede. È utile quando il confine è pulito, il percorso di misurazione è ovvio e il costo operativo dell'integrazione è inferiore al guadagno in termini di sicurezza o manutenibilità che crea. Altrimenti, il progetto diventa un bellissimo caso di studio su come dedicare molto tempo alla progettazione spostando lateralmente l’incertezza.
Questo è il vero anti-modello da evitare: non usare Rust, ma usarlo per mascherare l'assenza di chiarezza architettonica. Se il team non è in grado di spiegare dove inizia la proprietà, dove viene misurata la latenza, dove si incrociano i buffer e dove avviene il ripristino sotto stress, la modifica della lingua non salverà il progetto. Renderà solo il fallimento più bilingue.
Il confine conta più del sermone
Un errore comune nelle discussioni su C++ e Rust è presupporre che l'uso di Rust rimuova automaticamente il pericolo. Non è così. Cambia il luogo in cui si trova il pericolo. In HFT, la questione dei confini è particolarmente importante perché i percorsi caldi raramente finiscono al confine della lingua. Terminano IA confini della rete, IA confini delle code, IA confini della pianificazione, IA confini di FFI e IA confini del layout dei dati.
Se un componente Rust deve passare in un adattatore di scambio C++, parlare con una coda nativa, passare i dati a un motore strategico con presupposti di layout rigorosi o mantenere un comportamento deterministico attraverso le transizioni dei confini, allora il vero lavoro di ingegneria non è "abbiamo usato Rust". Il vero lavoro è con quanta cura è stata definita e verificata la cucitura. Comportamenti non sicuri possono ancora verificarsi a causa di mancata corrispondenza di ABI, confusione sulla proprietà, copie nascoste, errori di coda o sorprese temporali. La lingua da sola non è il tuo modello di governance. Il confine è.
Questo è il motivo per cui i team maturi parlano di un percorso stretto e caldo e di una superficie stretta e poco sicura. Non si basano su slogan come "sicurezza della memoria per impostazione predefinita" per risolvere quello che è fondamentalmente un problema di progettazione del sistema. Le buone squadre fanno domande più brutte e quindi più utili. Dove avviene la copia? Dov'è il salto in coda? Quale parte possiede il buffer? Quale percorso assegna? Cosa succede durante la contropressione? Cos'è rigiocabile? Cosa può essere valutato isolatamente e cosa deve essere valutato end-to-end perché le vittorie locali hanno una lunga tradizione di diventare delusioni globali?
Il vantaggio della chiarezza dei confini non è solo in termini di prestazioni. È sanità organizzativa. Una volta che i collegamenti sono espliciti, i team possono dividere le responsabilità senza perdere la responsabilità. Gli ingegneri delle prestazioni sanno cosa misurare. Le persone della piattaforma sanno cosa non toccare con nonchalance. I team di sicurezza e rischio possono ragionare sulle superfici di guasto. Gli acquirenti e la leadership ricevono una lettura tecnica che impedisce alla stanza di discutere in tondo. Un buon confine non aiuta semplicemente il compilatore. Aiuta l'azienda.
Questo è uno dei motivi per cui l’architettura HFT trae vantaggio da una postura cooperativa e orientata all’ecosistema piuttosto che da una postura da eroe. I migliori sistemi di solito non sono costruiti da una persona che ne dimostra la purezza. Sono costruiti da un gruppo che concorda su interfacce, misurazioni e proprietà dei fallimenti in modo così approfondito che il sistema rimane spiegabile anche quando il mercato smette di essere amichevole.
Casi pratici che vale la pena risolvere prima
Il primo progetto più intelligente raramente è "riscrivere il percorso caldo". Questo è l'equivalente tecnico di entrare in una casa e decidere che il primo atto utile è sostituire l'intero scheletro prima di verificare quale tubo sta già allagando la cucina.
Il primo progetto migliore è uno di questi:
Lavoro di prova degli addetti alla lavorazione del mangime
Se il team discute se l'analisi, la normalizzazione, l'accodamento o il trasferimento siano davvero il problema della latenza, costruire prima il percorso delle prove. Cattura il traffico rappresentativo, riproducilo in modo deterministico e forza il sistema a confessare dove il tempo e il jitter stanno effettivamente entrando nella catena. La maggior parte dei sistemi HFT non hanno bisogno di più ideologia qui. Hanno bisogno di una macchina della verità migliore.
Il percorso delle prove dovrebbe essere sufficientemente valido da consentire l'utilizzo della stessa traccia da parte di addetti alle prestazioni, sviluppatori e leadership quando è necessaria una dura chiamata di definizione delle priorità. Una volta che la storia dei tempi viene condivisa, metà dell’attrito politico svanisce perché la stanza non negozia più con le voci.
Gateway e pulizia dei confini del rischio
Molti stack non vengono rovinati dalla logica strategica principale. Sono rovinati dalla trascuratezza dei confini tra rischio, logica di accesso e coordinamento operativo. Un’attenta riscrittura o ristrutturazione di questi punti può migliorare l’affidabilità e la diagnosticabilità senza il rischio commerciale di toccare prima il circuito assolutamente più caldo.
È anche qui che garanzie linguistiche più forti possono creare un reale valore economico. Se diventa più facile ragionare sulla convalida degli ordini, sulla limitazione e sui messaggi di rischio, l’intero sistema diventa più calmo. I sistemi calmi sono più rapidi da cambiare e più economici da governare.
Pulizia ibrida del piano di controllo
Se gli strumenti dell'operatore, gli aiutanti per la distribuzione, le utilità di ripristino o gli strumenti di riproduzione sono fragili, Rust può essere un buon candidato in questo caso. Questi componenti spesso determinano la salute dell’intera organizzazione anche quando non si trovano nel percorso più veloce del microsecondo. Strumenti più puliti possono rendere il sistema caldo più calmo senza pretendere che ogni binario nella tenuta meriti lo stesso linguaggio.
La vittoria nascosta qui è la salute. Strumenti migliori riducono la quantità di archeologia alle 2 del mattino che una squadra deve eseguire solo per rispondere a domande operative di base. Ciò significa meno rituali di emergenza, meno sistemi fragili gestiti da una sola persona e una migliore cooperazione tecnica a lungo termine. Nelle organizzazioni ingegneristiche mature, questo conta più di quanto le persone dicano ad alta voce.
Laboratorio pratico: costruisci un piccolo rilevatore di gap di sequenza e rendilo onesto
Manteniamo il laboratorio piccolo e utile. I sistemi HFT vivono e muoiono grazie alla disciplina della sequenza molto prima di raggiungere un'affascinante logica strategica. Questo programma giocattolo riproduce un flusso simile a un feed e segnala dove sono apparse le lacune.
Lo scopo dell'esercizio non è distribuire questo codice esatto. Il punto è insegnare l’abitudine a preservare lo stato deterministico sotto pressione. La disciplina della sequenza è uno dei primi luoghi in cui un sistema commerciale dimostra di rispettare le prove o dimostra che sta ancora bluffando.
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";
}
}
Costruire
Su Linux o macOS:
g++ -O2 -std=c++20 -o gap_detector main.cpp
./gap_detector
Su Windows:
cl /O2 /std:c++20 main.cpp
.\main.exe
Risultato previsto:
gap expected=1004 received=1007
gap expected=1009 received=1011
Perché questo piccolo esercizio è importante
Perché forza il giusto tipo di pensiero:
- aggiornamento deterministico dello stato
- sequenza onesta
- riproduzione prima della teoria
- comportamento limitato e misurabile
Questo è già più HFT di un numero sorprendente di diapositive di conferenze.
Se vuoi rendere l'esercizio più realistico, aggiungi timestamp, pacchetti che arrivano in ritardo e reimpostazioni di sessione specifiche per la sede. Ciò che conta non è rendere il codice più teatrale. Ciò che conta è costruire il riflesso secondo cui ogni affermazione sul flusso di dati dovrebbe essere verificabile, riproducibile e sufficientemente piccola da poter essere spiegata.
Attività di prova per appassionati
- Trasferisci lo stesso rilevatore su Rust e confronta non la vanità del benchmark, ma la chiarezza dei confini, l'attrito delle dipendenze e la facilità con cui ciascuna versione si adatta IA tuoi strumenti esistenti.
- Estendi la riproduzione in modo che i pacchetti mancanti possano successivamente arrivare fuori ordine, quindi decidi se il rilevatore deve memorizzarli nel buffer, rifiutarli o contrassegnarli.
- Aggiungi temporizzazione e misura la differenza tra una riproduzione supportata da vettori e una riproduzione supportata da buffer ad anello.
- Introduci un’allocazione non necessaria sul percorso caldo e misura quanto velocemente una decisione “piccola” inizia a contaminare il risultato.
- Aggiungi un ramo di registrazione all'interno di
on_packete osserva quanto velocemente l'osservabilità diventa un sabotaggio quando viene posizionata con noncuranza.
Riepilogo
La vera conversazione tra C++ e Rust in HFT non riguarda quale linguaggio meriti la mitologia più bella. Riguarda quali parti del sistema necessitano di un controllo diretto, quali beneficiano di impostazioni predefinite più forti e quali confini possono essere resi sufficientemente onesti da supportare la progettazione ibrida senza illusioni.
C++ domina ancora i percorsi HFT più interessanti perché il dominio premia il controllo sul layout della memoria, sull'accodamento, sul comportamento dei cavi, sulla profilazione, sulla riproduzione e sull'integrazione con un ecosistema maturo a bassa latenza. Rust è utile laddove la correttezza, l'esplicitezza e la manutenibilità creano più valore rispetto IA costi aggiuntivi di attrito dell'ecosistema. Entrambi possono appartenere a uno stack serio. La mossa degli adulti è decidere dove e lasciare che siano le prove piuttosto che il fandom del linguaggio a tenere il punteggio.
Le squadre che riescono a farlo bene fanno qualcosa di molto poco affascinante e molto efficace. Smettono di chiedersi quale lingua li salverà e iniziano a chiedersi quale confine merita quale tipo di disciplina. Questo cambiamento sembra modesto, ma rappresenta la differenza tra l’architettura come marchio e l’architettura come verità operativa. In HFT, la verità di solito invecchia meglio.
Riferimenti
- Specifiche NASDAQ TotalView-ITCH: ITCH
- FIX Standard della comunità commerciale: FIX
- Documentazione DPDK: https://doc.dpdk.org/guides/
- Linux documentazione di timestamp: Linux
- Brendan Gregg sui grafici delle fiamme: https://www.brendangregg.com/flamegraphs.html
- Il Rust Libro delle prestazioni: Rust