boost::interprocess message_queue 性能 - 相当慢?

发布于 2024-11-11 04:29:45 字数 712 浏览 2 评论 0 原文

我需要一个超快的 MQ 机制,发送方和接收方都是在 Windows 平台上用 C++ 编写的。

我当前使用 RCF-C++ 进行 IPC 的实现速度约为 20,000 条消息/秒通过 Windows 命名管道。

我正在根据 演示应用程序,测量到每秒大约 48,000 条消息,考虑到当我在同一台计算机上编写一个简单的内存映射文件通信时(在 C# 中使用 < a href="http://techmikael.blogspot.com/2010/02/blazing-fast-ipc-in-net-4-wcf-vs.html" rel="noreferrer">此博客文章中的代码),我每秒收到大约 150,000 条消息。

知道为什么我的 boost message_queue 性能如此缓慢,以及我可以尝试如何改进它吗?

I need an ultra-fast MQ mechanism, where both sender and receiver are written in C++, on Windows platform.

My current implementation using RCF-C++ for IPC is clocking at around 20,000 msg/sec over Windows Named Pipes.

I am testing the perf of boost::interprocess Message Queues according to the demo app, and am measuring around 48,000 messages/sec, which is surprisingly slow, considering that when I cooked up a simple Memory Mapped File communication on the same machine (in C# using code from this blog post), I got around 150,000 messages/sec.

Any idea about why I'm getting such slow performance out of boost message_queue, and what I can try to improve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

神魇的王 2024-11-18 04:29:45

Daniel的答案是其中的一部分,但这里有一个更大的问题:boost::interprocess基本上将队列维护为共享内存中的数组,并且在发送消息时,boost::interprocess:message_queue基于新消息的优先级来查找该消息应放置在数组中的位置,然后 std::backward_copy 存储所有其他消息为其腾出空间。如果您始终使用相同的优先级,您的消息将被放置在开头(因为它是最新的),因此当时缓冲区中的任何消息都将被向后复制以为它腾出空间,这需要时间。 (请参阅queue_free_msg方法的实现)。

如果您不需要消息具有优先级,而只想要一个常规的 FIFO 队列,那么这种方法比使用 Circular 慢很多Buffer:插入(发送)的性能随着队列大小的增长而迅速恶化。

更新:我在维基百科上的注释的帮助下编写了一个在内部使用循环缓冲区的message_queue版本,这是一个巨大的成功。

Daniel's answer is part of it, but there is a bigger issue here: boost::interprocess basically maintains the queue as an array in shared memory, and upon sending a message, the boost::interprocess:message_queue does a binary search based on the new message's priority to find where the message should be placed in the array, and then std::backward_copys all the other messages to make room for it. If you always use the same priority, your message will be placed at the beginning (since it's the newest), and so whatever messages you have in the buffer at that time will be backwards_copied to make room for it, which takes time. (See implementation of the queue_free_msg method).

If you don't need messages to have priorities, and just want a regular FIFO queue, then this approach is a lot slower than using a Circular Buffer: the performance of insertions (sends) deteriorates rapidly as the size of the queue grows.

UPDATE: I wrote a version of the message_queue that uses a circular buffer internally, with help from the notes on wikipedia, and this was a big success.

孤者何惧 2024-11-18 04:29:45

正如Boost文档所述、boost::interprocess::shared_memory_object是在Win32中使用内存映射文件实现的。而且,boost 的消息队列也使用模拟的共享内存对象。 (对于本机Win32共享内存,boost单独提供了windows_shared_memory类。)

因此,为了使消息队列有更好的性能,您必须使用本机Win32共享内存对象实现您自己版本的消息队列。在我的实验中,更换它后,性能显着提高。

请注意,如果更改为 Win32 本机共享内存,则必须注意共享内存的“删除”。 POSIX共享内存和Win32共享内存有不同的删除策略。

As Boost document states, boost::interprocess::shared_memory_object is implemented using memory mapped file in Win32. And, boost's message queue is using that simulated shared memory object as well. (For native Win32 shared memory, boost provides windows_shared_memory class separately.)

For better performance of message queue, therefore, you have to implement your own version of message queue using native Win32 shared memory object. In my experiments, after replacing it, performance increased noticeably.

Note that, if you change to Win32 native shared memory, you must take care of 'deletion' of the shared memory. POSIX shared memory and Win32 shared memory has different policy of deletion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文