LINUX.ORG.RU

Проблема с темпом выдачи данных 1,6 ms (Qt c++, tcp)

 , ,


0

4

Linux Astra. При передачи данных возникают задержки около 200, 50 миллисекунд через несколько тысяч пачек, есть зависимость от взаимодействия с рабочим столом (сворачивание окон) . Протокол: запрос-ответ, управляющий пакет 100 байт, ответный 800 байт, темп 1,6 мс. Используются линуксовые сокеты,в setsockopt TCP_NODELAY 1. На поток выдачи выставлен scheduler SCHED_FIFO с приоритетом 98, прерывания обрабатываются на отдельном ядре. Пересобирал ядро для повышения частоты прерываний CONFIG_HZ с 250 до 1000. Проблема сохраняется на тестовой программе, выдающей константный массив. Прошу помочь.

Ответ на: комментарий от tailgunner

Дампы всё равно смотреть и грепать придётся. Сутевой код лишний раз не надо будет править что бы включать выключать замер. Сетевой стек положит таймштамп в пакет всё эффективней, чем среднестатистический товарищ на колене(хотя те наносекунды конечно рано считать, но зачем они если можно без них).

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

pon4ik ★★★★★ ()

я конечно ничего не понимаю в сетевом программировании, с/с++ и тем более Qt. но

1. написать изолированную отдельную программу, которая делает только это - шлет пакеты, без всяких qt и без остальной программы.

2. запустить ту же программу на любом другом компьютере с другим дистром. 90% что проблема повторится и там, а если не проявится, то это уже «интересно...»

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

thomasbug ()
Ответ на: комментарий от pon4ik

Дампы всё равно смотреть и грепать придётся

Или не придется. В любом случае, время этого еще не пришло.

Сетевой стек положит таймштамп в пакет всё эффективней, чем среднестатистический товарищ на колене

Ты вообще заметил порядок требуемых цифр? Какие наносекунды, о чем ты - тут миллисекунды из TCP пытаются выжимать.

tailgunner ★★★★★ ()
Ответ на: комментарий от pon4ik

Сетевой стек положит таймштамп в пакет всё эффективней, чем среднестатистический товарищ

но сетевой стек штамповать в какой-то другой момент времени, т.к. на другом этапе. а ТС озабочен (насколько можно понять) времением начиная от момента вызова метода в его коде.

thomasbug ()
Ответ на: комментарий от tailgunner

Может ты и прав, х3, имхо, если у автора имеются нефункциональные требования всё равно он полезет в дампы, рано или поздно.

миллисекунды из TCP пытаются выжимать

Таки да, автор так и не удосужился сообщить что у него за стек. Может там кофеварка по wifi.

pon4ik ★★★★★ ()
Ответ на: комментарий от thomasbug

В смысле на сколько блокируется условный send? Я не увидел этого в описании задачи, хм.

Кстати, текущая методика замера тоже должна бы появиться в студии, если автор ожидает сектор приз на барабане.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

имхо, если у автора имеются нефункциональные требования всё равно он полезет в дампы, рано или поздно.

Может быть (я не понимаю, как это поможет разобраться с времянкой, но, наверное, это недостаток моего опыта). Но я считаю, что пока надо работать на тупом юзерском уровне.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

вероятно надо и в payload положить время из программы и попросить сетевой стек (сетевой стек (поправь если я не прав) - это код ядра насколько я понимаю) поставить штамп. таком образом, если задержка возникает ДО - это будет видно, т.к. время из payload и время из поля пакета (если я правильно понимаю) сильно разойдутся.

thomasbug ()
Ответ на: комментарий от thomasbug

А вот это тоже крайне отличная идея. Только обычно можно так не делать, а просто сравнить таймштамп в логе и в пакете. Того же boost::log тут хватит за глаза с таким разрешением, да может даже и штатных кутишных логов хватит, только не помню я как там таймштампы включить. Только SO_TIMESTAMPING для этого не нужен, можно просто времена отправки пакетов из дампа брать.

pon4ik ★★★★★ ()
Последнее исправление: pon4ik (всего исправлений: 1)
Ответ на: комментарий от thomasbug

Всё это можно сделать, конечно. Но сначала надо написать простые клиент и сервер, которые просто передают метку времени, и посмотреть, что получится - возможно, всё будет работать как надо, и тогда зачем все предлагаемые сложности?

Вообще, разговор напоминает разговор терапевта с хирургами - хирургам хочется с места в карьер что-нибудь резать.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Как предложил товарищ выше - сравниваешь дельту между временем вылета в пакете и событиями в коде на критическом пути. Потом бинарным поиском вверх по стеку ищешь тот блокирующий вызов на котором затык. Потом, смотришь, кто дерётся за эту блокировку.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

просто сравнить таймштамп в логе и в пакете

Логи для получения меток времени, серьезно? O_o Метки времени приема пакетов надо сохранять во внутренней памяти и печатать по завершению программы.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

ну я вообще просто теоретизирую, я выше написал, что не имею такой квалификации.

что-нибудь резать

согласен, советовать легче чем все эти тесты готовить проводить. там выше уже какой-то только «тяжелой артиллерии» не предложили. iron_bug наверное предложила бы сразу зачистить до дорожек и щупом осциллографа ждать фронт.

thomasbug ()
Ответ на: комментарий от tailgunner

Можно, зависит от частоты событий и от устройства куда лог идёт.

На практике, системы с микросекундными задержками вполне себе успешно логгируют своё поведение без особых проблем(хотя и не так подробно, как хотелось бы). Правда делают это обычно через всякие lttng и самопальные аналоги или на худой конец на рам диск или в самый край через mmap. Тут у нас ситуация на пару порядков попроще, поэтому, любого более менее адекватного логгера хватит, кмк.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Правда делают это обычно через всякие lttng и самопальные аналоги

Ну я и предлагаю самопальный аналог, который, к тому же, не требует вообще ничего, кроме std.

tailgunner ★★★★★ ()
Ответ на: комментарий от tailgunner

Кстати, я в том году замерял spdlog, он конечно всасывает проприетарным решениям. Но накладные расходы на лог в 50% случаев укладывались в 50% случаев в 2us, в 90% случаев в 8us в 99.99% случаев в 20us. В среднем было 1.3us.

Конфиг машины только не записан к сожалению, помню только что был какой то зион в сфере запущенный.

И это - без изысков, с записью на ssd со стандартными настройками FS и в перемешку с типовым payload.

pon4ik ★★★★★ ()
Ответ на: комментарий от tailgunner

Тем, что это костыль который выкинешь потом, а логи можно оставить, они ещё не раз пригодятся, пока в них упираться не начнёшь как минимум, а ТС похоже не скоро начнёт.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

это костыль который выкинешь потом

Я думаю, что ТС выкинет написанные сервер и клиент сразу после того, как решит проблему. Это не продакшен-код, это именно код на выброс.

tailgunner ★★★★★ ()
Ответ на: комментарий от pon4ik

системы с микросекундными задержками вполне себе успешно логгируют своё поведение без особых проблем

вроде как продвинутые логировщики должны уметь класть записи в буфер и из него уже сбрасывать периодически.

thomasbug ()
Ответ на: комментарий от tailgunner

Я думаю нет, зачем? Ведь конфигурации могут быть разными, пусть будет бенчмарк текущего окружения, что бы сразу сказать кастомеру - у Вас - сеть гвно, вот вам лог с лабораторного конфига, сравните как с Вашим. Это слегка удобней, чем каждый раз писать код на выброс.

А так то ты прав во всём, первое с чего надо начинать, писать echo вариант своего решения и смотреть, а можно ли с нужной скоростью хотя бы без изысков.

pon4ik ★★★★★ ()
Ответ на: комментарий от thomasbug

Да, в ядре даже для этого подсистема есть, но в детали я не вникал. В юзерспейсе тоже можно неплохо, видел сорцы самопального решения на mmap где наносекундные(сотни ns) издержки на логгирование в 99.99% случаев, но, глубоко о5 же туда не лазил.

pon4ik ★★★★★ ()
Ответ на: комментарий от pon4ik

Машина - двухъядерный ноут, попробую логи, как только доберусь до машины.

Замерял tbb таймером внутри метода, задержка 200 вылезла на полном цикле работы (запрос-ответ).

Send не блокирует поток больше чем на несколько микросекун.

Speed_nik ()

Какие настройки сетевого стека (sysctl -a | grep [rw]mem)? У тебя вообще хватает буферов?

Ещё бывает такая забавная штука: SMM. Процессор там не 200 мс, конечно, проводит, но фиг его знает, что у тебяза железка.

И вообще, зачем TCP для RPC? IP/UDP гораздо проще, чем IP/TCP?

mv ★★★★★ ()
Ответ на: комментарий от Speed_nik

Если есть доступ к более чистому окружению - я бы рекомендовал там попробовать.

Можно попробовать конечно тут сессию удалённой отладки на твоём конфиге провести, но она будет ооочень растянута по времени. И нет гарантий, что ты не сольёшься :)

Вон товарищъ модератор уже в отказ пошёл;)

pon4ik ★★★★★ ()
Ответ на: комментарий от anonymous

Я бы для начала предоставил минимальный пример с проблемой. 99% код кривой. А вы уже там и ядро собрались тюнить. У меня через один свич до целевого устройства < 1 mc всегда.

anonymous ()