ZeroMQ — pub/sub latency

Я изучаю ZeroMQ, чтобы узнать, подходит ли он для приложения с программным обеспечением в реальном времени. Я был очень рад видеть, что задержка для небольших полезных нагрузок была в диапазоне 30 микросекунд или около того. Однако в моих простых тестах я получаю около 300 микросекунд.

У меня есть простой издатель и подписчик, в основном скопированные из примеров из Интернета, и я отправляю один байт через локальный хост.

Я играл около двух дней с разными sockopts, и я вычеркиваю.

Любая помощь будет оценена по достоинству!

издатель:

#include <iostream>
#include <zmq.hpp>
#include <unistd.h>

#include <sys/time.h>


int main()
{
    zmq::context_t context (1);
    zmq::socket_t publisher (context, ZMQ_PUB);
    publisher.bind("tcp://*:5556");

    struct timeval timeofday;
    zmq::message_t msg(1);
    while(true)
    {
        gettimeofday(&timeofday,NULL);
        publisher.send(msg);
        std::cout << timeofday.tv_sec << ", " << timeofday.tv_usec << std::endl;
        usleep(1000000);
    } 
}  

подписчик:

#include <iostream>
#include <zmq.hpp>
#include <sys/time.h>


int main()
{
    zmq::context_t context (1);
    zmq::socket_t subscriber (context, ZMQ_SUB);
    subscriber.connect("tcp://localhost:5556");
    subscriber.setsockopt(ZMQ_SUBSCRIBE, "", 0);

    struct timeval timeofday;
    zmq::message_t update;
    while(true)
    {
        subscriber.recv(&update);
        gettimeofday(&timeofday,NULL);
        std::cout << timeofday.tv_sec << ", " << timeofday.tv_usec << std::endl;
    }
}

person Willy Pell    schedule 27.06.2015    source источник
comment
Прочитав это и ваши комментарии к этот вопрос , лучше всего обратиться к списку рассылки zmq   -  person Jason    schedule 01.07.2015


Ответы (2)


Реально ли определение задачи?

Говоря о *-проектировании в реальном времени, проверка возможностей архитектуры важнее, чем сама последующая реализация.

Если вы берете исходный код как есть, ваши показания (которые, к сожалению, не были опубликованы вместе с вашими фрагментами кода для перекрестной проверки реплицированного повторного теста MCVE) не будут служить многому, так как числа не различают, какие части ( сколько времени ) было потрачено на отправляющую сторону loop-er, на отправляющую сторону zmq-сбор данных/копирование/планирование/форматирование на уровне провода/датаграмму-отправку и на принимающую сторону выгрузку из носителя/копирование/декодирование/шаблон -соответствие/распространение на буфер(ы) приемника

Если вы заинтересованы во внутреннем устройстве ZeroMQ, есть хорошие заметки по применению, связанные с производительностью.

Если вы стремитесь к дизайну с минимальной задержкой, сделайте следующее:

  • remove all overheads
    • replace all tcp-header processing from the proposed PUB/SUB channel
    • избежать всех некардинальных логических накладных расходов на обработку (нет смысла тратить время на подписку на стороне подписчика (конечно, более новые версии ZMQ перешли на фильтрацию на стороне издателя, но идея ясна) с сопоставлением с образцом, закодированным в выбранной обработке архетипа (использование ZMQ_PAIR позволяет избежать любого такого, независимо от класса транспорта) - если предполагается что-то заблокировать, то скорее измените сигнализацию расположение сокетов соответственно, чтобы главным образом избежать блокировки (это должна быть система реального времени, как вы сказали выше)
    • примените «маскирование задержки», где это возможно, в целевой многоядерной / многоядерной аппаратной архитектуре, чтобы выжать последние капли свободного времени из возможностей вашего оборудования / инструментов ... сравнение с экспериментальными настройками с большим количеством операций ввода-вывода. -threads' help zmq::context_t context( N );, где N > 1

Недостающая цель:

Как сказала Алиса в Стране Чудес более века назад, когда цель не определена, любая дорога ведет к цели.

Имея амбиции мягкого реального времени, не должно быть проблем с указанием максимально допустимой сквозной задержки и, исходя из этого, ограничения задержки транспортного уровня.

Без этого 30 мкс, 300 мкс или даже 3 мс не имеют смысла сами по себе, поэтому никто не может решить, «достаточно» ли этих цифр для какой-то подсистемы или нет.

Разумный следующий шаг:

  • определить горизонт(ы) стабильности в реальном времени... при использовании для управления в реальном времени
  • определить проектные ограничения в режиме реального времени... для сбора(-ов) сигналов/данных, для задачи(-й) обработки, для служб самодиагностики и управления
  • избегайте любой блокировки с точки зрения дизайна и проверяйте/докажите, что блокировка никогда не появится при всех возможных обстоятельствах реального мира [формальные методы доказательства готовы для такой задачи] (никто не хотел бы видеть AlertPanel [Ожидание данных] во время следующей посадки самолета или в последнюю очередь перед тем, как беспилотный автомобиль врежется прямо в стену, прекрасный вид [песочные часы] animated-icon пока он перемещает песок, в то время как система управления занята, какая бы причина этого ни стояла за этим, разрушительно блокирующим образом.

Количественные цели имеют смысл для тестирования.

Если заданный порог позволяет иметь горизонт устойчивости 500 мс (что может быть безопасным значением для медленного гидропривода/контура управления, но может не сработать для системы управления управляемой ракетой, тем меньше для любой [массы и импульса] безинерционной] безынерционной системы (аналогично семейству DSP систем управления RT)), вы можете протестировать от начала до конца, если ваша обработка подходит посередине.

Если вы знаете, что ваш входящий поток данных приносит около 10 КБ каждые 500 мкс, вы можете протестировать свой дизайн, сможет ли он справиться с всплеском трафика или нет.

Если вы тестируете, ваш макет не достигает цели (не соответствует показателям производительности / ограниченного времени), вы довольно хорошо знаете, где дизайн или где архитектура нуждается в улучшении.

person user3666197    schedule 21.07.2015

Сначала убедитесь, что вы запускаете производителя и потребителя на разных физических ядрах (не HT). Во-вторых, это ОЧЕНЬ зависит от железа и ОС. В последний раз, когда я измерял ввод-вывод ядра (4-5 лет назад), результаты действительно были от 10 до 20 мкс для системных вызовов отправки/получения. Вы должны оптимизировать настройки вашего ядра для низкой задержки и установить TCP_NODELAY.

person BitWhistler    schedule 21.07.2015