ZeroMQ - латентност на публикуване / суб

Разглеждам ZeroMQ, за да видя дали е подходящ за приложение в меко реално време. Бях много доволен да видя, че закъснението за малки полезни натоварвания е от порядъка на около 30 микросекунди. В моите прости тестове обаче получавам около 300 микросекунди.

Имам обикновен издател и абонат, основно копиран от примери извън мрежата и изпращам един байт през localhost.

Играх около два дни с различни 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-retest) няма да служат много, тъй като числата не разграничават кои части ( колко време ) са изразходвани за цикъл от страна на изпращане, zmq-data-acquisition/copy/schedulling/wire-level formatting/datagram-dispatch от страна на изпращане и разтоварване от страната на приемане от media/copy/decode/pattern - съпоставяне/разпространение към буфер(и) на приемник

Ако се интересувате от вътрешните елементи на ZeroMQ, има налични добри бележки за приложението, свързани с производителността.

Ако се стремите към дизайн с минимално забавяне, направете:

  • remove all overheads
    • replace all tcp-header processing from the proposed PUB/SUB channel
    • избягвайте всички некардинални логически разходи от обработката (няма смисъл да прекарвате време от страната на абонамента ( разбира се, по-новите версии на ZMQ са преминали към филтриране от страна на publisher, но идеята е ясна) със съпоставяне на шаблони, кодирано в избраната обработка на архетипа (използването на ZMQ_PAIR избягва всяко такова, независимо от транспортния клас) - ако е предназначено да блокира нещо, тогава по-скоро променете сигнализирането съответно оформление на сокета, така че по принцип да се избегне блокиране (това трябва да е система в реално време, както казахте по-горе)
    • приложете „маскиране на латентност“, където е възможно, в целевите многоядрени/многоядрени хардуерни архитектури, така че да изстискате последните капки свободно време от възможностите на вашия хардуер/инструменти ... сравнителен анализ с експериментални настройки с повече I/O -помощ за нишките zmq::context_t context( N );, където N > 1

Липсваща цел:

Както каза Алиса в страната на чудесата преди повече от век, когато няма дефинирана цел, всеки път води до целта.

Имайки амбиция за меко реално време, няма да има проблем да се посочи максимално позволено закъснение от край до край и от това да се изведе ограничение за закъснение на транспортния слой.

Ако не го направите, 30 us, 300 us или дори 3 ms нямат значение сами по себе си, така че никой не може да реши дали тези цифри са „достатъчни“ за дадена подсистема или не.

Разумна следваща стъпка:

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

Количествените цели имат смисъл за тестване.

Ако даден праг позволява да има хоризонт на стабилност от 500 ms (което може да е безопасна стойност за забавен хидравличен задвижващ механизъм/контролен контур, но може да не успее да работи за система за управление на управляема ракета, толкова по-малко за всяка [маса и импулс- of-inertia]-less система (подобно на фамилията DSP на RT-control-systems)), можете да тествате от край до край, ако вашата обработка пасва между тях.

Ако знаете, че вашият входящ поток от данни носи около 10 kB на всеки 500 us, можете да тествате дизайна си дали може да поддържа темпото с бурния трафик или не.

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

person user3666197    schedule 21.07.2015

Първо се уверете, че стартирате производител и потребител на различни физически ядра (не HT). Второ, зависи МНОГО от хардуера и ОС. Последният път, когато измервах IO на ядрото (преди 4-5 години), резултатите наистина бяха 10 до 20us около системните повиквания за изпращане/приемане. Трябва да оптимизирате настройките на ядрото си до ниска латентност и да зададете TCP_NODELAY.

person BitWhistler    schedule 21.07.2015