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 имеют различную политику удаления.