повысить :: interprocess message_queue производительность - довольно медленно? - PullRequest
12 голосов
/ 02 июня 2011

Мне нужен сверхбыстрый механизм MQ, в котором отправитель и получатель написаны на C ++ на платформе Windows.

Моя текущая реализация, использующая RCF-C ++ для IPC, работает со скоростью около 20000 мсг / с по именованным каналам Windows.

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

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

Ответы [ 2 ]

13 голосов
/ 22 июня 2011

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

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

ОБНОВЛЕНИЕ: Я написал версию message_queue, которая использует внутренний буфер, с помощью заметок в Википедии , и это имело большой успех.

8 голосов
/ 02 июня 2011

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

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

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

...