ZeroMQ 比 boost asio 慢吗?

Is ZeroMQ slower than boost asio?

我正在尝试编写一个网络传输应用程序。

数据为二进制数据,每个数据包大小以800KB居多。

客户端每秒产生1000条数据。我想尽快传输数据。

当我使用 ZeroMQ 时,速度达到每秒 350 个数据,但是 boost asio 达到每秒 400 个(或更多)。

如您所见,这两种方法的性能都不好。

用于 ZeroMQ 的模式是 PUSH/PULL 模式,boost asio 是简单同步 I/O.

Q1:想问一下,ZeroMQ是不是只适合小消息?

Q2:有没有提高ZeroMQ速度的方法?

Q3: 如果 ZeroMQ 不能,请建议一些好的方法或库来改进这些数据传输。

数据速率

您正在尝试移动 800 MByte/second。这是一种怎样的联系?对于 tcp:// transport-class 它必须非常快速,例如100 Gbit/s 以太网,非常奇特。

所以我假设这是一个 ipc:// transport-class 连接。在这种情况下,您可以使用 ZeroMQ zerocopy 函数进行改进,从而避免重复复制数据。

在正常传输中,您必须将数据复制到 zmq 消息中,必须将其复制到 ipc 管道中,再次复制出来,然后在接收端复制回新的 zmq 消息中.所有这些复制需要 4 x 800 = 2.4 GByte/sec 内存带宽,当缓存冲突开始发挥作用时,这已占典型 PC 系统总内存带宽的相当大的百分比。使用 zerocopy 应该 将其减半。

零复制的替代方案 - 零传输

如果您正在使用ipc://,那么请考虑不通过套接字发送数据,而是通过套接字发送对数据的引用。

我以前混合使用 zmq 和信号量锁定的 C++ stl::queue,使用 zmq 只是为了它的模式(在我的例子中是 PUSH/PULL), stl::queue 携带指向数据的共享指针,并保持数据不变。发件人锁定队列,将共享指针放入其中,然后通过 zmq 套接字发送简单消息(例如“1”)。接收者读取“1”并将其用作锁定队列并从中拉出共享指针的提示。因此,指向数据的共享指针已通过 stl::queue 在 ZMQ 模式中从一个线程传输到另一个线程,但数据本身保持不变。我所做的只是在线程之间传递数据的所有权。只要发送的共享指针在发送后立即超出范围并且发送者不使用它来修改或访问数据,它就会工作。

PUSH/PULL 处理起来还算不错——每封邮件只会发送给一个收件人。与 PUB/SUB 进行这样的混合需要更多的努力,并且接收到的消息必须被视为 read-only,因为每个接收者都将有一个共享指针,指向与其他人相同的数据块。

邮件大小

我不知道 zmqtp 一次传输有多大块,但我猜它在 protocol:data 比率方面相对有效。