1 Punkte von GN⁺ 2024-07-09 | 1 Kommentare | Auf WhatsApp teilen

Designmuster für C++-Low-Latency-Anwendungen

  • Autoren: Paul Bilokon, Burak Gunduz
  • Eingereicht am: 8. September 2023
  • Thema: Optimierung von Low-Latency-Code mit besonderem Schwerpunkt auf Hochfrequenzhandelssystemen (HFT)

Wichtige Beiträge

  • Erstellung eines Low-Latency-Programming-Repositorys: Praktischer Leitfaden einschließlich strenger statistischer Benchmarks
  • Optimierung einer marktneutralen statistischen Arbitrage-Strategie: Deutliche Verbesserungen bei Geschwindigkeit und Rentabilität
  • C++-Implementierung des Disruptor-Musters: Leistungssteigerung gegenüber traditionellen Queueing-Methoden

Bewertungsmetriken

  • Geschwindigkeit
  • Cache-Nutzung
  • statistische Signifikanz usw.

Zentrale Techniken

  • Cache-Warming: Verringerung der Latenz durch Initialisierung des Caches
  • Constexpr: Leistungssteigerung durch Auswertung konstanter Ausdrücke zur Compile-Zeit

Zukünftige Ausrichtung

  • Erweiterung des Repositorys
  • Test der optimierten Handelsalgorithmen in Echtzeit-Handelsumgebungen
  • Integration des Disruptor-Musters und der Handelsalgorithmen für ein umfassendes System-Benchmarking

Zielpublikum

  • Praktiker in Wissenschaft und Industrie

Zusammenfassung von GN⁺

Diese Arbeit behandelt Designmuster zur Verbesserung der Leistung von Low-Latency-Anwendungen, insbesondere in Hochfrequenzhandelssystemen. Das Low-Latency-Programming-Repository und die Implementierung des Disruptor-Musters dürften für Praktiker ein nützlicher Leitfaden sein. Techniken wie Cache-Warming und constexpr tragen wesentlich zur Verringerung der Latenz bei. Diese Arbeit dürfte für alle, die sich für Performance-Optimierung interessieren, äußerst aufschlussreich sein.

1 Kommentare

 
GN⁺ 2024-07-09
Hacker-News-Kommentar
  • Eine kurze Einführung in das Thema

  • Studierende im Grundstudium kennen die grundlegenden Elemente der Performance-Optimierung bereits

    • Sie lernen Basiskonzepte wie Branch Prediction, Cache-Kohärenz und Instruction Cache
  • Überraschend ist, dass false sharing als Ursache für Performance-Einbußen nicht behandelt wird

  • Ebenso überraschend ist, dass Optimierungs-Hint-Attribute wie [[likely]] und [[unlikely]] nicht behandelt werden

  • Fortgeschrittene Elemente der Performance-Optimierung werden nicht behandelt

    • etwa bestimmte IO-APIs, Synchronisationsprimitive, IPC-Mechanismen oder Compiler-Built-ins
  • Was Low-Latency-Programmierer brauchen, ist Wachsamkeit gegenüber unnötigen Allokationen, Kopien usw.

    • Man braucht die Gewohnheit, durch Benchmarks Ursachen für Performance-Verlust zu finden
  • Beim Schreiben eines Low-Latency-Servers wurde klar, dass Vektor-IO-Operationen langsamer sind, als kleine Objekte in einen zusammenhängenden Puffer zu kopieren

    • Es wird betont, dass es keine kostenlosen Kopien gibt
  • Die Testergebnisse liefern t-Statistik und p-Wert

    • Die t-Statistik zeigt das Ergebnis des Unit-Root-Tests der Residuen an
    • Der p-Wert gibt die Wahrscheinlichkeit an, dass die Nullhypothese des Tests wahr ist
  • Dieser Teil wirkt, als sei er mit einem LLM geschrieben worden

  • Das Beispiel, bei dem Schlusskurse einmal täglich über fünf Jahre analysiert und Spreads mit 65 Mikrosekunden Latenz berechnet werden, wirkt seltsam

    • Im inneren Loop werden keine Statistiken berechnet
    • 65 Mikrosekunden sind für den inneren Loop zu langsam
    • Es scheint ein Beispiel zu sein, um Optimierungstechniken zu üben
  • Es wird eine in C++ geschriebene Implementierung einer Aktienbörse geteilt

    • Sie verwendet das LMAX-Disruptor-Muster
    • Es gibt Pläne, sie in Rust neu zu schreiben
    • In Rust sind Speicherverwaltung und Abhängigkeiten einfacher
  • Es wurde eine C++-Logging-Bibliothek geschrieben

    • Sie ist LMAX Disruptor ähnlich
    • Sie wird in der HFT-Community verwendet
    • Sie ermöglicht detailliertes Logging ohne Performance-Einbußen
    • Sie löst das Problem, dass Kollegen aus Sorge vor Performance-Verlust wichtige Informationen nicht loggen
  • Die Effizienz von Compile-Time-Dispatch ergibt sich daraus, dass die Entscheidung über den Funktionsaufruf bereits beim Kompilieren getroffen wird

    • Wenn der Compiler die aufgerufene Funktion statisch bestimmen kann, kann er den Code der aufgerufenen Funktion direkt inlinen
    • Dadurch entfällt jeglicher Overhead des Funktionsaufrufs und zusätzliche Optimierungen werden möglich
  • Es wird ein Vortrag von der CppCon 2017 geteilt

    • Das Thema lautet, dass sich Mikrosekunden wie eine Ewigkeit anfühlen
    • Als professioneller Entwickler sollte man sich das gesamte Material ansehen
  • Es wird infrage gestellt, ob es überhaupt einen Grund für die Existenz von Hochfrequenzhandel gibt

    • Man beschwert sich darüber, dass Bitcoin Energie verschwendet, aber Hochfrequenzhandel hat einen rein negativen gesellschaftlichen Einfluss