IPC-Leistung: Named Pipe vs Socket

114

Jeder scheint zu sagen, dass Named Pipes schneller sind als IPC-Sockets. Wie viel schneller sind sie? Ich würde es vorziehen, Sockets zu verwenden, da diese eine bidirektionale Kommunikation ermöglichen und sehr flexibel sind, aber Geschwindigkeit gegenüber Flexibilität wählen, wenn es sich um einen beträchtlichen Betrag handelt.

user19745
quelle
10
Ihr Kilometerstand wird variieren. :) Profilieren Sie die typische Verwendung für Ihre beabsichtigte Anwendung und wählen Sie die bessere der beiden aus. Profilieren Sie dann anonyme Pipes, Sockets anderer Domänen und Familien, Semaphoren und gemeinsam genutzte Speicher- oder Nachrichtenwarteschlangen (SysV und POSIX), Echtzeitsignale mit einem Datenwort oder was auch immer. pipe(2)(ähm mkfifo(3)?) ist vielleicht der Gewinner, aber Sie werden es nicht wissen, bis Sie es versuchen.
Pilcrow
2
SysV-Nachrichtenwarteschlangen FTW! Ich habe keine Ahnung, ob sie schnell sind, ich habe nur eine Schwäche für sie.
Tom Anderson
4
Was ist in diesem Fall "Geschwindigkeit"? Gesamtdatenübertragungsrate? Oder Latenz (wie schnell gelangt das erste Byte zum Empfänger)? Wenn Sie eine schnelle lokale Datenübertragung wünschen, ist der gemeinsam genutzte Speicher kaum zu übertreffen. Wenn Latenz ein Problem ist, wird die Frage interessanter ...
Ian Ni-Lewis

Antworten:

64

Ich würde vorschlagen, dass Sie zuerst den einfachen Weg gehen und den IPC-Mechanismus sorgfältig isolieren, damit Sie von Muffe zu Rohr wechseln können, aber ich würde definitiv zuerst mit Muffe gehen. Sie sollten sicher sein, dass die IPC-Leistung ein Problem darstellt, bevor Sie eine präventive Optimierung durchführen.

Und wenn Sie aufgrund der IPC-Geschwindigkeit in Schwierigkeiten geraten, sollten Sie in Betracht ziehen, auf gemeinsam genutzten Speicher zu wechseln, anstatt auf Pipe umzusteigen.

Wenn Sie Übertragungsgeschwindigkeitstests durchführen möchten, sollten Sie socat ausprobieren , ein sehr vielseitiges Programm, mit dem Sie fast jede Art von Tunnel erstellen können.

Shodanex
quelle
47

Die besten Ergebnisse erzielen Sie mit der Shared Memory- Lösung.

Named Pipes sind nur 16% besser als TCP-Sockets .

Ergebnisse werden mit IPC-Benchmarking erzielt :

  • System: Linux (Linux Ubuntu 4.4.0 x86_64 i7-6700K 4.00GHz)
  • Nachricht: 128 Bytes
  • Anzahl der Nachrichten: 1000000

Rohrbenchmark:

Message size:       128
Message count:      1000000
Total duration:     27367.454 ms
Average duration:   27.319 us
Minimum duration:   5.888 us
Maximum duration:   15763.712 us
Standard deviation: 26.664 us
Message rate:       36539 msg/s

Benchmark für FIFOs (Named Pipes):

Message size:       128
Message count:      1000000
Total duration:     38100.093 ms
Average duration:   38.025 us
Minimum duration:   6.656 us
Maximum duration:   27415.040 us
Standard deviation: 91.614 us
Message rate:       26246 msg/s

Message Queue-Benchmark:

Message size:       128
Message count:      1000000
Total duration:     14723.159 ms
Average duration:   14.675 us
Minimum duration:   3.840 us
Maximum duration:   17437.184 us
Standard deviation: 53.615 us
Message rate:       67920 msg/s

Shared Memory-Benchmark:

Message size:       128
Message count:      1000000
Total duration:     261.650 ms
Average duration:   0.238 us
Minimum duration:   0.000 us
Maximum duration:   10092.032 us
Standard deviation: 22.095 us
Message rate:       3821893 msg/s

Benchmark für TCP-Sockets:

Message size:       128
Message count:      1000000
Total duration:     44477.257 ms
Average duration:   44.391 us
Minimum duration:   11.520 us
Maximum duration:   15863.296 us
Standard deviation: 44.905 us
Message rate:       22483 msg/s

Benchmark für Unix-Domain-Sockets:

Message size:       128
Message count:      1000000
Total duration:     24579.846 ms
Average duration:   24.531 us
Minimum duration:   2.560 us
Maximum duration:   15932.928 us
Standard deviation: 37.854 us
Message rate:       40683 msg/s

ZeroMQ-Benchmark:

Message size:       128
Message count:      1000000
Total duration:     64872.327 ms
Average duration:   64.808 us
Minimum duration:   23.552 us
Maximum duration:   16443.392 us
Standard deviation: 133.483 us
Message rate:       15414 msg/s
Chronoxor
quelle
1
Vielen Dank für das detaillierte Benchmarking. Meinen Sie "multiprocessing.Queue" mit "Message Queue"?
Ovunccetin
1
Nachrichtenwarteschlange ist eine System-XSI-Nachrichtenwarteschlange ( man7.org/linux/man-pages/man0/sys_msg.h.0p.html )
Chronoxor
34

Ich werde Shodanex zustimmen, es sieht so aus, als würden Sie vorzeitig versuchen, etwas zu optimieren, das noch nicht problematisch ist. Wenn Sie nicht wissen, dass Steckdosen ein Engpass sein werden, würde ich sie einfach verwenden.

Viele Leute, die auf Named Pipes schwören, finden ein wenig Ersparnis (abhängig davon, wie gut alles andere geschrieben ist), erhalten jedoch Code, der mehr Zeit für das Blockieren einer IPC-Antwort benötigt als für nützliche Arbeit. Sicher, nicht blockierende Schemata helfen dabei, aber diese können schwierig sein. Ich kann sagen, dass die Beschleunigung Jahre damit verbracht hat, alten Code in die Moderne zu bringen. In den meisten Fällen, die ich gesehen habe, ist die Beschleunigung fast gleich Null.

Wenn Sie wirklich glauben, dass Sockets Sie verlangsamen werden, gehen Sie mit gemeinsamem Speicher aus dem Gate und achten Sie dabei sorgfältig darauf, wie Sie Sperren verwenden. Auch hier kann es vorkommen, dass Sie eine kleine Beschleunigung feststellen. Beachten Sie jedoch, dass Sie einen Teil davon verschwenden, indem Sie auf Sperren für gegenseitigen Ausschluss warten. Ich werde keine Reise in die Futex-Hölle befürworten ( na ja , 2015 nicht mehr ganz die Hölle, abhängig von Ihrer Erfahrung).

Pfund für Pfund sind Sockets (fast) immer der beste Weg, um IPC für den Benutzerbereich unter einem monolithischen Kernel zu erhalten. Und (normalerweise) am einfachsten zu debuggen und zu warten.

Tim Post
quelle
2
Vielleicht werden wir eines Tages in einer fernen utopischen Zukunft einen völlig neuen, modularen, modernen Kernel haben, der implizit alle (Interprozess- und andere) Fähigkeiten bietet, die wir derzeit über Glasscherben laufen, um dies zu erreichen ... aber hey ... man kann träumen
Gukki5
27

Beachten Sie, dass Sockets nicht unbedingt IP (und TCP oder UDP) bedeuten. Sie können auch UNIX-Sockets (PF_UNIX) verwenden, die eine spürbare Leistungsverbesserung gegenüber der Verbindung zu 127.0.0.1 bieten

Yuliy
quelle
1
Was ist mit Windows?
Pacerier
1
@Pacerier Leider können Sie unter Windows keine lokalen Sockets erstellen, wie dies unter UNIX der abstrakte Namespace ist. Ich habe festgestellt, dass PF_UNIX-Sockets wesentlich schneller sind (> 10%) als die meisten anderen auf dieser Seite beschriebenen Methoden.
EntangledLoops
1
devblogs.microsoft.com/commandline/af_unix-comes-to-windows update, Unix-Sockets sind jetzt in Windows 10 verfügbar.
eri0o
11

Wenn Sie keine Geschwindigkeit benötigen, sind Steckdosen der einfachste Weg!

Wenn es um Geschwindigkeit geht, ist die schnellste Lösung Shared Memory, nicht Named Pipes.

Damien
quelle
8

Für die bidirektionale Kommunikation mit Named Pipes:

  • Wenn Sie nur wenige Prozesse haben, können Sie zwei Pipes in zwei Richtungen öffnen (processA2ProcessB und processB2ProcessA).
  • Wenn Sie viele Prozesse haben, können Sie für jeden Prozess Ein- und Ausgänge öffnen (processAin, processAout, processBin, processBout, processCin, processCout usw.).
  • Oder du kannst wie immer Hybrid fahren :)

Named Pipes sind recht einfach zu implementieren.

Zum Beispiel habe ich ein Projekt in C mit Named Pipes implementiert, dank der Kommunikation zwischen Standard-Dateieingabe und -ausgabe (fopen, fprintf, fscanf ...) war es so einfach und sauber (wenn das auch eine Überlegung ist).

Ich habe sie sogar mit Java codiert (ich habe Objekte serialisiert und über sie gesendet!)

Benannte Rohre haben einen Nachteil:

  • Sie lassen sich nicht auf mehreren Computern wie Sockets skalieren, da sie auf dem Dateisystem basieren (vorausgesetzt, das gemeinsam genutzte Dateisystem ist keine Option).
Daghan
quelle
8

Ein Problem mit Sockets ist, dass sie keine Möglichkeit haben, den Puffer zu leeren. Es gibt einen sogenannten Nagle-Algorithmus, der alle Daten sammelt und nach 40 ms löscht. Wenn es also um Reaktionsfähigkeit und nicht um Bandbreite geht, sind Sie mit einer Pipe möglicherweise besser dran.

Sie können den Nagle mit der Socket-Option TCP_NODELAY deaktivieren, aber das Leseende empfängt niemals zwei Kurznachrichten in einem einzigen Leseanruf.

Also teste es, ich habe nichts davon gefunden und speicherabgebildete Warteschlangen mit Pthread-Mutex und Semaphor im gemeinsamen Speicher implementiert, um viele Kernel-Systemaufrufe zu vermeiden (aber heute sind sie nicht mehr sehr langsam).

Lothar
quelle
3
"Also test it" <- Worte, nach denen man leben kann.
Koshinae
6

Benannte Rohre und Muffen sind funktional nicht gleichwertig. Sockets bieten mehr Funktionen (sie sind zunächst bidirektional).

Wir können Ihnen nicht sagen, welche besser abschneiden wird, aber ich vermute sehr, dass es keine Rolle spielt.

Unix-Domain-Sockets machen so ziemlich das Gleiche wie TCP-Sockets, aber nur auf dem lokalen Computer und mit (vielleicht etwas) geringerem Overhead.

Wenn ein Unix-Socket nicht schnell genug ist und Sie viele Daten übertragen, sollten Sie den gemeinsam genutzten Speicher zwischen Ihrem Client und Server verwenden (was viel komplizierter einzurichten ist).

Unix und NT haben beide "Named Pipes", aber sie unterscheiden sich völlig im Funktionsumfang.

MarkR
quelle
1
Nun, wenn Sie 2 Rohre öffnen, erhalten Sie auch Bidi-Verhalten.
Pacerier
4

Sie können eine leichte Lösung wie ZeroMQ [ zmq / 0mq ] verwenden. Es ist sehr einfach zu bedienen und dramatisch schneller als Steckdosen.

Amit Vujic
quelle
2
Vielleicht gefällt Ihnen Amit, Martin SUSTRIKs nächstes Kunstwerk - POSIX-konform nanomsg. Wie auch immer, begrüße und genieße diesen großartigen Ort und werde ein aktiv beitragendes Mitglied.
user3666197