1 Punkte von GN⁺ 2024-08-27 | 1 Kommentare | Auf WhatsApp teilen

vmsplice ist zu schnell

  • Einige Programme verwenden den Systemaufruf vmsplice, um Daten schneller durch Pipes zu bewegen
  • Es wurde festgestellt, dass Linux-Pipes langsamer als erwartet sind, wenn vmsplice nicht verwendet wird
  • Es wird an einem Programm gearbeitet, das Morsecode schnell kodiert/dekodiert, und dafür werden Pipes verwendet

Schreiben von Daten unter idealen Bedingungen

  • Das folgende Programm kopiert Daten ohne Systemaufrufe
  • Mit AVX-512 läuft es mit 167 GB/s
  • Auch bei deaktiviertem AVX-512 und Tests mit AVX2 sowie SSE2 wurde dieselbe Geschwindigkeit von 167 GB/s erreicht
  • Solange Vektorisierung verwendet wird, lassen sich 167 GB/s erreichen

Tatsächliches Schreiben von Daten in eine Pipe

  • Ein Programm zum Schreiben in eine Pipe wurde erstellt und gemessen; dabei wurden 17 GB/s erreicht
  • Das ist zehnmal langsamer als das Schreiben in einen Puffer
  • Das Profiling zeigte, dass der Großteil der Zeit im Aufruf write verbraucht wird
  • In der Funktion pipe_write geht viel Zeit für die Allokation von Speicherseiten verloren
  • Das eigentliche Kopieren der Daten macht nur 20 % der CPU-Zeit aus, ist aber immer noch doppelt so langsam wie __memset_avx512_unaligned_erms

Hilfe durch vmsplice

  • vmsplice verschiebt Puffer aus dem Userspace in den Kernel, ohne sie zu kopieren
  • Mit vmsplice lassen sich 210 GB/s erreichen
  • vmsplice umgeht den teuren Teil des Systemaufrufs write

Fazit

  • Das Schreiben in Pipes ist zehnmal langsamer als das Schreiben in rohen Speicher
  • Das liegt an den Kosten für das Sperren von Puffern sowie für das Sichern und Wiederherstellen des SIMD-Kontexts
  • splice und vmsplice vermeiden diese Kosten und bewegen Daten effizient

Zusammenfassung von GN⁺

  • Dieser Artikel erklärt, wie sich die Leistung von Linux-Pipes mit vmsplice maximieren lässt
  • vmsplice verschiebt Daten direkt, ohne sie in den Kernel-Speicher zu kopieren, und verbessert dadurch die Leistung erheblich
  • Das ist nützlich für Programme zur Hochgeschwindigkeits-Datenverarbeitung wie Morsecode-Kodierung/-Dekodierung
  • Andere Projekte mit ähnlicher Funktionalität sind unter anderem splice und sendfile

1 Kommentare

 
GN⁺ 2024-08-27
Hacker-News-Kommentar
  • Der Grund, warum JMP nicht durch RET ersetzt wird, ist die Option CONFIG_RETHUNK

    • Im Disassembly von objdump sieht man, dass RET durch JMP __x86_return_thunk ersetzt wurde
    • Relevante Links: Link1, Link2
  • Die NOP-Instruktionen am Anfang und Ende der Funktion ermöglichen es ftrace, Tracing-Instruktionen einzufügen

    • Sie stammen aus den Makros ASM_CLAC und ASM_STAC
    • Wenn X86_FEATURE_SMAP erkannt wird, werden sie zur Laufzeit mit den Instruktionen CLAC und STAC gefüllt
    • Relevante Links: Link3, Link4, Link5
  • Das Side-Project eines Nutzers schlägt einen Systemaufruf vor, der einen Ringpuffer für File Descriptors bereitstellt

    • Wenn beide Enden einer Pipe den Ringpuffer unterstützen, kann derselbe Ringpuffer gemappt werden, sodass Zero-Copy-IO ohne Kernel-Aufrufe möglich wird
    • Er sucht Mitwirkende
    • Relevanter Link: Link6
  • Linux-Pipes als „langsam“ zu bezeichnen ist so, als würde man einen Toyota Corolla als „langsam“ bezeichnen

    • In den meisten Fällen sind sie schnell genug
    • Außer in extremen Fällen gibt es keinen Grund, nach etwas Schnellerem zu suchen
  • Auf modernen CPUs ist rep movsb genauso schnell wie die schnellste vektorisierte Version

    • Der Name der Kernel-Funktion „copy_user_enhanced_fast_string“ deutet darauf hin
    • Die CPU-Features ERMS und FSRM machen das möglich
  • AVX512 verbraucht viel Strom und führt zu CPU-Frequenzskalierung

  • Man erlebt erneut den „hug of death“ von Hacker News

    • Dank gecachter WordPress-Seiten ist die Lage besser, aber es dauert immer noch einige Sekunden
  • Es wäre interessant, eine Version mit io_uring zu sehen

    • Mit Kernel- und vorab geteilten Puffern könnte man Kopien vermeiden und den Overhead von Systemaufrufen reduzieren
  • Zu behaupten, dass das Laden des Blogs etwa 20 Sekunden dauert, ist gewagt

  • Fast jede Form von IPC ist „langsam“

    • Man hat sich entschieden, für Sicherheit einen Performance-Preis zu zahlen
  • Ursprünglich war nicht klar, warum splice so langsam ist

    • Es wurde darauf hingewiesen, warum es langsamer als vmsplice ist, aber nicht, warum genau das so ist
    • Es muss einen Grund geben, warum es nicht mit vmsplice neu implementiert werden kann