Boost:: interprocess message_queue - довольно медленный?

Мне нужен сверхбыстрый механизм MQ, где оба отправителя и получателя написаны на С++ на платформе Windows.

Моя текущая реализация с использованием RCF-С++ для IPC работает со скоростью около 20 000 msg/sec по именам имен Windows.

Я тестирую perf of boost:: interprocess Message Queues в соответствии с демонстрационное приложение, и я измеряю около 48 000 сообщений в секунду, что удивительно медленный, учитывая, что когда я приготовил простую связь с файлами Memory Mapped File на том же компьютере (в С#, используя код из этого сообщения в блоге) Я получил около 150 000 сообщений в секунду.

Любая идея о том, почему я получаю такую ​​медленную производительность из boost_queue boost, и что я могу попытаться ее улучшить?

Ответ 1

Ответ Дэниела является частью этого, но здесь есть большая проблема: boost:: interprocess в основном поддерживает очередь как массив в общей памяти, а при отправке сообщения boost:: interprocess: message_queue выполняет двоичный поиск на основе нового приоритета сообщения, чтобы найти, где сообщение должно быть помещено в массив, а затем std::backward_copy все другие сообщения, чтобы освободить место для этого. Если вы всегда используете один и тот же приоритет, ваше сообщение будет размещаться в начале (начиная с самого нового), и поэтому любые сообщения, которые у вас есть в буфере в это время, будут обращены назад, чтобы освободить место для этого, что требует времени. (См. Реализацию метода queue_free_msg).

Если вам не нужны сообщения с приоритетами и просто нужна очередная очередь FIFO, то этот подход намного медленнее, чем использование Кругового буфера: производительность входов (отправлений) быстро ухудшается по мере увеличения размера очереди.

UPDATE: Я написал версию message_queue, которая использует внутренний буфер вокруг буфера в википедии, и это был большим успехом.

Ответ 2

В качестве документа Boost state, boost:: interprocess:: shared_memory_object реализуется с использованием файла с отображением памяти в Win32. Кроме того, в очереди сообщений с расширенным использованием используется также объект с разделяемой памятью. (Для родной общей памяти Win32 boost обеспечивает класс windows_shared_memory отдельно.)

Для повышения производительности очереди сообщений вам необходимо реализовать собственную версию очереди сообщений, используя собственный объект общей памяти Win32. В моих экспериментах, после его замены, производительность заметно увеличилась.

Обратите внимание, что если вы перейдете на собственную разделяемую память Win32, вы должны позаботиться об "удалении" разделяемой памяти. Общая память POSIX и разделяемая память Win32 имеют различную политику удаления.