Низкое время ожидания чтения порта UDP - PullRequest
13 голосов
/ 06 декабря 2011

Я читаю один элемент данных с порта UDP.Важно, чтобы при этом чтении было минимально возможное время ожидания.В настоящее время я читаю с помощью метода async_receive_from библиотеки boost :: asio.Кто-нибудь знает, какую задержку я буду испытывать между доставкой пакета на сетевую карту и методом обратного вызова, вызываемым в моем коде пользователя?

Boost - очень хорошая библиотека, но достаточно общая, есть ли альтернатива с более низкой задержкой?

Все мнения о написании сетевых программ UDP с низкой задержкой приветствуются.РЕДАКТИРОВАТЬ: Другой вопрос, есть ли относительно реальный способ оценить задержки, которые я испытываю между NIC и пользовательским режимом?

Ответы [ 2 ]

17 голосов
/ 06 декабря 2011

Ваше время ожидания будет варьироваться, но оно будет далеко не лучшим из того, что вы можете получить.Вот несколько вещей, которые будут стоять на вашем пути к лучшей задержке:

Boost.ASIO

  1. Он постоянно выделяет / освобождает память для хранения «состояния»для вызова функции обратного вызова, связанной с вашей операцией чтения.
  2. Она делает ненужной mutex блокировку / разблокировку для поддержки разорванного сочетания асинхронных и синхронизирующих подходов.
  3. Худшее,он постоянно добавляет и удаляет дескрипторы событий из базового механизма уведомлений.

В общем, asio - хорошая библиотека для разработчиков приложений высокого уровня, но она поставляется с большим ценником имного процессорного цикла ест гремлины.Другая альтернатива - libevent, она намного лучше, но все еще нацелена на поддержку многих механизмов уведомления и независимость от платформы.Ничто не может побить нативные механизмы, например epoll.

Прочие вещи

  1. UDP-стек.Это не очень хорошо работает для чувствительных к задержке приложений.Одним из самых популярных решений является OpenOnload.Он обходит стек и работает напрямую с вашим NIC.
  2. Планировщик.По умолчанию планировщик оптимизирован для пропускной способности, а не задержки.Вам нужно будет настроить и настроить свою ОС, чтобы ориентировать ее на задержку.Linux, например, имеет много «rt» патчей для этой цели.
  3. Остерегайтесь не спать.Когда ваш процесс находится в спящем режиме, вы никогда не получите хорошую задержку при пробуждении по сравнению с постоянно горящим процессором и ожиданием прибытия пакета.
  4. Помехи другим IRQ, процессам и т. Д.

Я не могу сказать вам точные цифры, но при условии, что вы не будете получать много трафика, используя Boost и обычное ядро ​​Linux, с обычным оборудованием, ваша задержка будет колебаться где-то между ~ 50 микросекундами и ~ 100 миллисекундами.Это немного улучшится, когда вы получите больше данных, и после некоторого момента начнете падать, и всегда будет ранжироваться.Я бы сказал, что если вы согласны с этими цифрами, не пытайтесь оптимизировать.

1 голос
/ 11 сентября 2013

Я думаю, что при использовании recv () в потоке «spin» и присоединении потока к одному ядру процессора (Processor Affinity), задержка должна быть ниже, чем при использовании select (), точность select () варьируется от 1до 10 микросекунд, в то время как в моем тесте крутильная петля на 1 микросекунду.

...