我正在尝试编写网络传输应用程序。
数据是二进制数据,每个数据包大小大多为800KB。
客户端每秒产生1000个数据。我想尽快传输数据。
当我使用ZeroMQ时,速度达到每秒350个数据,但增强asio每秒达到400(或更多)。
正如您所看到的,两种方法的表现并不好。
用于ZeroMQ的模式是 PUSH/PULL
模式,boost asio是简单的同步I / O.
Q1:我想问一下,ZeroMQ是否只适合小消息?
Q2:有没有办法提高ZeroMQ速度?
Q3:如果ZeroMQ不能,请建议一些好的方法或库来改善这种数据传输。
答案 0 :(得分:3)
数据率
你试图移动800 MByte /秒。这是什么联系?对于tcp://
传输类,它必须非常快速,例如100 Gbit / s以太网,非常具有异国情调。
所以我认为它是 ipc://
传输类连接。在这种情况下,您可以使用ZeroMQ zerocopy函数进行改进,这样可以重复复制数据。
通过正常传输,您必须将数据复制到zmq消息中,该消息必须复制到ipc
管道中,再次复制出来,并在接收端复制回新的zmq消息。所有这些复制都需要4 x 800 = 2.4 GByte / sec的内存带宽,当缓存冲突发挥作用时,它是典型PC系统总内存带宽的一个可观的百分比。使用zerocopy 应 将其减半。
替代零拷贝 - 零转移
如果您使用ipc://
,请考虑不通过套接字发送数据,而是通过套接字发送对数据的引用。
我以前混合使用zmq和信号量锁定C ++ stl::queue
,使用zmq只是为了它的模式(在我的情况下为PUSH/PULL
),{{1}携带共享指针指向数据,并保持数据不变。发送方锁定队列,将共享指针放入其中,然后通过zmq套接字发送简单消息(例如“1”)。收件人读取“1”并将其用作提示来锁定队列并从中拉出共享指针。因此,数据的共享指针已经通过stl::queue
以ZMQ模式从一个线程传输到另一个线程,但数据本身保持不变。我所做的就是在线程之间传递数据的所有权。它的工作原理只要发送的共享指针在发送后立即超出范围,发送方不会使用它来修改或访问数据。
stl::queue
处理起来并不算太糟糕 - 每条消息只发送给一个收件人。与PUSH/PULL
进行这样的混合会花费更多的努力,并且接收的消息必须被视为只读,因为每个接收者将拥有与其他所有人相同的数据块的共享指针。
邮件大小
我不知道zmqtp一次传输有多大块,但我猜它在协议方面相对有效:数据比率。