Data Rate
Sie versuchen, 800 MByte/Sekunde zu bewegen. Welche Art von Verbindung ist das? Für eine tcp://
Transportklasse müsste es etwas ziemlich schnelles, z.B. 100 Gbit/s Ethernet, das ist ziemlich exotisch.
Also ich nehme an, dass es eine ipc://
Transportklasse-Verbindung ist. In diesem Fall können Sie eine Verbesserung erzielen, indem Sie ZeroMQ-Zerocopy-Funktionen verwenden, die das wiederholte Kopieren der Daten ersparen.
Bei einer normalen Übertragung müssen Sie Daten in eine zmq-Nachricht kopieren, die in eine ipc
-Pipe kopiert, erneut kopiert und auf der Empfängerseite in eine neue zmq-Nachricht zurückkopiert werden muss. All dieses Kopieren erfordert eine Speicherbandbreite von 4 × 800 = 2,4 GByte/s, was, wenn Cache-Konflikte auftreten, einen beträchtlichen Prozentsatz der gesamten Speicherbandbreite eines typischen PC-Systems ausmacht. Mit Zerocopy sollte schneiden Sie das in zwei Hälften.
Alternative to Zero Copy - ohne Umschaltzeit
Wenn Sie ipc://
verwenden, dann sollten die Daten nicht durch die Buchsen senden, sondern Verweise auf die Daten, die durch die Buchsen senden.
Ich habe früher Einsatz von ZMQ gemischt und ein Semaphor gesperrt C++ stl::queue
, mit ZMQ einfach für sie Muster (PUSH/PULL
in meinem Fall) sind, die stl::queue
gemeinsame Zeiger auf Daten zu tragen, und die Daten immer noch verlassen. Der Absender sperrt die Warteschlange, fügt einen gemeinsamen Zeiger ein und sendet dann eine einfache Nachricht (z. B. "1") durch einen zmq-Socket. Der Empfänger liest die "1" und verwendet diese als einen Hinweis, um die Warteschlange zu sperren und einen geteilten Zeiger davon abzuziehen.Somit wurde ein geteilter Zeiger auf Daten von einem Thread zu einem anderen in einem ZMQ-Muster über eine stl::queue
übertragen, aber die Daten selbst sind still geblieben. Alles, was ich getan habe, ist Besitz der Daten zwischen Threads übergeben. Es funktioniert so lange, wie der gemeinsame Zeiger, den das Senden hat, unmittelbar nach dem Senden aus dem Gültigkeitsbereich hinausgeht und nicht von dem Absender verwandt wird, um die Daten zu ändern, oder auf die Daten zuzugreifen.
PUSH/PULL
ist nicht zu schlecht zu behandeln - jede Nachricht geht an nur einen Empfänger. Es würde mehr Aufwand erfordern, eine solche Mischung mit PUB/SUB
zu erstellen, und empfangene Nachrichten müssten als schreibgeschützt behandelt werden, da jeder Empfänger einen gemeinsamen Zeiger auf den gleichen Datenblock wie alle anderen haben würde.
Nachrichtengröße
Ich habe nicht Ahnung, wie groß ein Stück zmqtp zu einer Zeit überträgt, aber ich würde vermuten, dass es in Bezug auf Protokoll relativ effizient ist: Daten-Verhältnis.
@ user3666197, danke für das Aufpolieren! – bazza