Die Frage, die mich beschäftigt hat
Als ich die C#-Bindings für iceoryx2 entwickelt habe, wollte ich eine Sache wirklich wissen: Wie schnell ist das im Vergleich zu den Standard-.NET-Alternativen?
Also habe ich einen umfassenden Benchmark gebaut.
Die Kandidaten
Drei Technologien im Vergleich:
- System.Threading.Channels: .NETs eingebaute Producer/Consumer-Queue
- Named Pipes: Klassische IPC über den Kernel
- iceoryx2: Zero-Copy IPC via Shared Memory
Was macht jede Technologie?
Channels übergibt Objektreferenzen innerhalb eines Prozesses. Schnell, aber keine echte IPC - funktioniert nicht zwischen Prozessen.
Named Pipes macht echte IPC. Die Daten gehen von deinem Prozess in den Kernel, dann vom Kernel in den anderen Prozess. Zwei Kopien. Zwei Context Switches. Pro Nachricht.
iceoryx2 mappt Shared Memory in beide Prozesse. Der Publisher schreibt die Daten einmal. Der Subscriber liest sie direkt. Keine Kopien. Kein Kernel auf dem Datenpfad.
Die Ergebnisse
Durchsatz
| Payload | Channels | Named Pipes | iceoryx2 |
|---|---|---|---|
| 8 B | 15,3M msg/s | 648K msg/s | 2,2M msg/s |
| 1 KB | 13,6M msg/s | 316K msg/s | 2,3M msg/s |
| 64 KB | 15,7M msg/s | 4,5K msg/s | 2,1M msg/s |
| 512 KB | 15,3M msg/s | 589 msg/s | 2,0M msg/s |
Channels sieht schnell aus, aber übergibt nur Referenzen. Für IPC-Vergleiche irrelevant.
Der spannende Vergleich ist Pipes vs iceoryx2:
- Kleine Nachrichten (8 B): iceoryx2 ist 3,3x schneller
- Große Nachrichten (512 KB): iceoryx2 ist 3.371x schneller
Der Durchsatz von Named Pipes bricht bei größeren Payloads komplett ein. Jedes Byte muss zweimal durch den Kernel. iceoryx2 bleibt konstant - das ist Zero-Copy in Aktion.
CPU-Verbrauch
| Payload | Channels | Named Pipes | iceoryx2 |
|---|---|---|---|
| 8 B | 180% | 1.257% | 195% |
| 512 KB | 181% | 1.183% | 195% |
Named Pipes lastet 12 CPU-Kerne aus, um nur einen Bruchteil des iceoryx2-Durchsatzes zu erreichen. iceoryx2 braucht 6x weniger CPU für die gleiche Arbeit.
Warum ist das so?
Named Pipes Architektur:
Prozess A → [Kopie] → Kernel Buffer → [Kopie] → Prozess B
syscall syscall
iceoryx2 Architektur:
Prozess A → [Pointer] → Shared Memory ← [Pointer] ← Prozess B
Keine Kopien. Keine Syscalls auf dem Datenpfad. Der Kernel ist nur beim Setup involviert.
Wann welche Technologie?
Channels: In-Process Producer/Consumer. Einfach, schnell, keine IPC.
Named Pipes: Kommunikation über Maschinen hinweg. Funktioniert übers Netzwerk. Einfaches Setup.
iceoryx2: IPC auf derselben Maschine, wenn Performance zählt. Robotik, Trading, Video-Processing, Echtzeitsysteme.
Work in Progress
Dieses Benchmarking und die Performance-Optimierung sind noch in Arbeit. Die Zahlen hier zeigen meinen aktuellen Stand.
Aktueller Scope: 1 Publisher, 1 Subscriber. Der einfachste Fall. Benchmarks für N Publisher zu M Subscribers folgen.
Wenn du Probleme mit der Methodologie findest, Ideen für Verbesserungen hast oder beitragen möchtest - ich freue mich über Feedback. Öffne ein Issue oder schick einen PR.
Der Code
Der komplette Benchmark-Code ist Open Source. Methodologie: 10-Sekunden-Runs, 2-Sekunden-Warmup, verschiedene Payload-Größen.
GitHub: https://github.com/patdhlk/iceoryx2-csharp-int/tree/performance-comparison

