Reputation: 11827
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?
Upvotes: 12
Views: 13796
Reputation: 11827
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_copy
s 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.
Upvotes: 14
Reputation: 987
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.
Upvotes: 8