LINUX.ORG.RU

select pthread задержки


0

0

Есть программулина в несколько нитей. На нити возложены различные задачи. В частности есть одна, интересующая нас нить. Эта нить опрашивает по TCP некое устройство. Протокол простой - запрос ответ, запрос ответ и т.д. Используется неблокирующий сокет и select. Запрос отсылается примерно раз в 20-30мс. Среднее время ответа < 1мс. Время ответа определяется так: определяется время до вызова select и сразу после. Машина на которой крутиться программа и опрашиваемое устройство соединены ethernet напрямую. То есть влияние промежуточного канального оборудования исключается. Проблема такая. Иногда время ответа становиться равным 208-210мс. Это для приложения очень критично. Как я вижу, где может быть проблема 1) устройство тормозит с ответом 2) какие-то сетевые заморочки 3) проблема в планировщике (данные по ethernet пришли, но процесс остаётся заблокированным по каким-то причинам). Для теста была написана маленькая программулина, которая только опрашивает устройство. Подобных задержек на ней не наблюдается. Причём независимо от того работает она одна или параллельно с основной. То есть устройство отвечает быстро и в сети всё в порядке. Остаётся причина 3. Дальше интереснее. Если тестовая программа работает параллельно с основной, то в основной нет этих задержек (по крайне мере суточный тест их не выявил). Как только тестовую задачу останавливаем, через некоторое время основная начинает отлавливать задержки. Включаем тестовую задержки исчезают. Ощущение, что данные как будто застраивают, и второй поток их проталкивает.

В чём может быт проблема? Как установить причину?

anonymous

Самая что ни на есть обычная ситуация дырявой абстракции. Какой-то программный код считает себя самым умным оптимизатором и при той самой задержке в 20-30 мс между запросами производит свою коварную оптимизацию.
Решение в лоб: тестовую задачу сделать штатной костылеподобной оптимизацией, т.е. посылать запросы чаще.

ShprotX
()

Проблема может ьыть в куче мест - от отладочной печати до ожидания в другой нити "большой" программы. Вообще-то для отлавливания таких ситуаций предназначены вещи вроде LTT и других трассировщиков.

По-быстрому можно запустить "большую" программу с SCHED_FIFO (или SCHED_RR).

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

> пальцем в небо - это не алгоритм Nagle? гугли про TCP_NODELAY

Блин, я и не заметил, что у него TCP. Кто ж по TCP срочные короткие пакеты шлет.

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

>Блин, я и не заметил, что у него TCP. Кто ж по TCP срочные короткие пакеты шлет.

если сессия установлена и не дергается, то здесь врятли UDP даст прирост. Хотя если с сетью жопа, то TCP тут начнет ретрансмиты ack-ов... но и в этом случае с UDP проблем будет не меньше, в смысле на уровне логики приложения. Здесь надо смотреть на суть приложения.

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

> Самая что ни на есть обычная ситуация дырявой абстракции. Какой-то > программный код считает себя самым умным оптимизатором и при той > самой задержке в 20-30 мс между запросами производит свою коварную > оптимизацию. > Решение в лоб: тестовую задачу сделать штатной костылеподобной > оптимизацией, т.е. посылать запросы чаще. Очень похоже на правду. Что сделал: стал опрашивать устройство чаше: раз в 10мс делаю последовательно (послал, получил ответ, послал, ответ, послал, ответ - там надо ) 3 запроса и задержек не наблюдаю. Кто может так портить жизнь? в ядре какие-нибудь алгоритмы оптимизации? Хоть проблема сейчас и не проявляется - нет уверенности, что она решена, поскольку причина не выявлены. Хочется добить ситуацию. Вообще компы становятся всё больше похожи на людей. Вот в данном случае, если не пинать, как следует, начинает филонить....

> пальцем в небо - это не алгоритм Nagle? гугли про TCP_NODELAY... нет это тут не причём. Алгоритм Nagle блокирует посылку малого пакета, если не получен ACK на предыдущий. В данном случае на уровне приложения не отправляется следующий запрос пока не получен ответ на предыдущий. (Устройство отсылает ACK вместе с ответом - проверено снифером). Единственно, где может быть задержка - отсылка ACK устройству на его ответ. Но это не может приводить к задержке в select. в любом случае проверил - не помогло (на малых скоростях запросов)

> Проблема может ьыть в куче мест - от отладочной печати до ожидания > в другой нити "большой" программы. Замер времени идёт сразу перед select и сразу после. Соответственно, проблема не в отладочной печати и т.п. Что касается "ожидания в другой нити "большой" программы." То на уровне приложения блокировок в этом месте нет (опять же время засекается только на select и эти замеры совпадают с значением timeout после вызова select). Если имелось ввиду, другая нить занимает процессор (на 200мс???), то почему сторонняя программа разруливает эту ситуацию? С приоритетами нитей кстати игрался - не влияет. Вообще загрузка процессора не превышает 1%.

> Вообще-то для отлавливания таких ситуаций предназначены вещи вроде > LTT и других трассировщиков. спасибо, посмотрю

> По-быстрому можно запустить "большую" программу с SCHED_FIFO (или > SCHED_RR). Не очень понял. Нити в ней запустить с SCHED_FIFO или всю программулину как нить пристыковать ... к чему? Поясните, пожалуйста.

> Блин, я и не заметил, что у него TCP. Кто ж по TCP срочные короткие > пакеты шлет. TCP - это данность.

> если сессия установлена и не дергается, то здесь врятли UDP даст > прирост. Хотя если с сетью жопа, то TCP тут начнет ретрансмиты > ck-ов... но и в этом случае с UDP проблем будет не меньше, в смысле > а уровне логики приложения. Здесь надо смотреть на суть приложения. Совершенно согласен.

Ну вот на большой скорости за полчаса ниотного подвиса (раньне было 1-2 раза в минуту).

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

форматирование ещё раз

> Самая что ни на есть обычная ситуация дырявой абстракции. Какой-то

> программный код считает себя самым умным оптимизатором и при той

> самой задержке в 20-30 мс между запросами производит свою коварную

> оптимизацию.

> Решение в лоб: тестовую задачу сделать штатной костылеподобной

> оптимизацией, т.е. посылать запросы чаще.

Очень похоже на правду. Что сделал: стал опрашивать устройство чаше: раз в 10мс делаю последовательно (послал, получил ответ, послал, ответ, послал, ответ - там надо ) 3 запроса и задержек не наблюдаю. Кто может так портить жизнь? в ядре какие-нибудь алгоритмы оптимизации?

Хоть проблема сейчас и не проявляется - нет уверенности, что она решена, поскольку причина не выявлены. Хочется добить ситуацию. Вообще компы становятся всё больше похожи на людей. Вот в данном случае, если не пинать, как следует, начинает филонить....

> пальцем в небо - это не алгоритм Nagle? гугли про TCP_NODELAY...

нет это тут не причём. Алгоритм Nagle блокирует посылку малого пакета, если не получен ACK на предыдущий. В данном случае на уровне приложения не отправляется следующий запрос пока не получен ответ на предыдущий. (Устройство отсылает ACK вместе с ответом - проверено снифером). Единственно, где может быть задержка - отсылка ACK устройству на его ответ. Но это не может приводить к задержке в select. в любом случае проверил - не помогло (на малых скоростях запросов)

> Проблема может ьыть в куче мест - от отладочной печати до ожидания

> в другой нити "большой" программы.

Замер времени идёт сразу перед select и сразу после. Соответственно, проблема не в отладочной печати и т.п. Что касается "ожидания в другой нити "большой" программы." То на уровне приложения блокировок в этом месте нет (опять же время засекается только на select и эти замеры совпадают с значением timeout после вызова select). Если имелось ввиду, другая нить занимает процессор (на 200мс???), то почему сторонняя программа разруливает эту ситуацию? С приоритетами нитей кстати игрался - не влияет. Вообще загрузка процессора не превышает 1%.

> Вообще-то для отлавливания таких ситуаций предназначены вещи вроде

> LTT и других трассировщиков.

спасибо, посмотрю

> По-быстрому можно запустить "большую" программу с SCHED_FIFO (или

> SCHED_RR).

Не очень понял. Нити в ней запустить с SCHED_FIFO или всю программулину как нить пристыковать ... к чему? Поясните, пожалуйста.

> Блин, я и не заметил, что у него TCP. Кто ж по TCP срочные короткие

> пакеты шлет.

TCP - это данность.

> если сессия установлена и не дергается, то здесь врятли UDP даст

> прирост. Хотя если с сетью жопа, то TCP тут начнет ретрансмиты

> ck-ов... но и в этом случае с UDP проблем будет не меньше, в смысле

> а уровне логики приложения. Здесь надо смотреть на суть приложения.

Совершенно согласен.

Ну вот на большой скорости за полчаса ниодного подвиса (раньне было 1-2 раза в минуту).

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

>> По-быстрому можно запустить "большую" программу с SCHED_FIFO (или > SCHED_RR).

> Не очень понял. Нити в ней запустить с SCHED_FIFO или всю программулину как нить пристыковать ... к чему? Поясните, пожалуйста.

Все нити пустить с SHCED_FIFO, назначив им разумные приоритеты. Возможно, у тебя затык не в нити, которая взаимодействует с сетью, а в другой нити. Например, в той, которой сетевая нить отдает данные. Инверсия приоритетов, бывает такое.

tailgunner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.