12

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

我当前使用RCF-C++进行 IPC 的实现在 Windows 命名管道上的时钟速度约为 20,000 msg/sec。

我正在根据演示应用程序测试 boost::interprocess Message Queues 的性能,并且测量到大约 48,000 条消息/秒,考虑到当我在同一台机器上编写一个简单的内存映射文件通信时(在C# 使用此博客文章中的代码),我每秒收到大约 150,000 条消息。

关于为什么我从 boost message_queue 中获得如此缓慢的性能以及我可以尝试改进它的任何想法?

4

2 回答 2

14

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

如果您不需要消息具有优先级,而只需要一个常规的 FIFO 队列,那么这种方法比使用循环缓冲区要慢得多:随着队列大小的增长,插入(发送)的性能会迅速下降。

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

于 2011-06-22T13:29:50.297 回答
8

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

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

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

于 2011-06-02T08:33:38.663 回答