epoll и задержка отправки

Я использую 64-разрядную версию Linux Linux scv 3.2.0-39-generic #62-Ubuntu SMP Thu Feb 28 00:28:53 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux и имею два процесса, использующих сокеты, которые работают на одном физическом хосте.

Один процесс (A) отправляет через сокет TCP/IP (это будет локальный сокет, если хост тот же) следующие части данных:

  1. 276 байт
  2. 16 байт

Это делается за 0,000023 секунды в процессе A. Данные отправляются, вызывая 2 раза API сокета send.

Другой процесс (B) получает данные через epoll, используя epoll_wait(efd, events, 10, 5). Данные принимаются следующим образом (время берется с clock_gettime(CLOCK_REALTIME, &cur_ts);, важна относительная разница):

  1. Чтение данных из буфера сокета по адресу 8051.177743 (276)
  2. Повторный вызов epoll 8051.177763
  3. Чтение данных из буфера сокета 8051.216250 (16)

задержка процесса получения составляет 0,038507 секунды. В основном, если отправляющий процесс A занимает менее мс, на принимающей стороне epoll для получения данных добавляется дополнительная задержка примерно 0,038 с. .

Ожидается ли это? Что я делаю не так?
Или как исправить ситуацию?

Спасибо


person Emanuele    schedule 01.04.2013    source источник
comment
Точка 3 — это когда возвращается второй вызов epoll.   -  person Emanuele    schedule 01.04.2013
comment
40 мс — это стандартный квант времени, выглядит как стандартное переключение контекста на одном ядре.   -  person Steve-o    schedule 01.04.2013
comment
Должен ли я отказаться от epoll, если я хочу уменьшить это отставание? Что ты посоветуешь?   -  person Emanuele    schedule 01.04.2013
comment
В настоящее время я вижу что-то эквивалентное, однако я получаю задержку в 0,2 секунды перед возвратом epoll_wait вместо 38 мс :(. Я не верю, что это свойственно epoll, потому что оно работает только с большим количеством fds. Что-то не так, и должна быть возможность объяснить, что именно.   -  person Carlo Wood    schedule 05.06.2019


Ответы (1)


Ожидается ли это? ...

да. Я ожидал этого. Вот почему:

Что я делаю неправильно? ...

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

... как я могу улучшить ситуацию?

Если вы хотите повысить производительность, используйте правильный инструмент. Не используйте epoll для одного сокета. Просто используйте старый добрый ванильный recv. Если вы работаете с двумя или тремя сокетами, рассмотрите возможность использования опроса или выбора. Если вы рискуете получить сотни, вы можете рассмотреть возможность использования epoll или kqueue.

person autistic    schedule 01.04.2013
comment
Действительно? 0,038 с только для вызова функции? Разве epoll не должен был быть O(1)? В любом случае, приложение должно иметь возможность управлять более чем 500 соединениями, поэтому я считаю, что другие методы, такие как 1 поток на соединение, кажутся непрактичными. - person Emanuele; 01.04.2013
comment
@Emanuele Я бы предположил, что epoll занимает примерно 0,038 с, независимо от того, даете ли вы ему небольшое количество сокетов или большое количество сокетов. Если нет, покажите мне sscce, и я скажу, что вы делаете неправильно. - person autistic; 01.04.2013
comment
@ Эмануэле, я думаю, это глупая идея. Переключение контекста, вероятно, обойдется еще дороже! Типичный компьютер имеет что, четыре ядра? Больше одного-двух потоков на ядро ​​было бы излишним. Если вам не нравится epoll, рассмотрите неблокирующий опрос или выберите цикл, работающий на всех четырех ядрах, каждое из которых обслуживает несколько сотен клиентов. Постарайтесь спроектировать свое решение так, чтобы свести к минимуму блокировки потоков, такие как мьютексы и блокирующие операции ввода-вывода, чтобы вы могли сосредоточиться на выполнении большего объема обработки для каждого потока, а не создавать больше потоков для выполнения большего объема обработки. - person autistic; 01.04.2013
comment
Даже если целевая система может иметь более 24 ядер? Как я уже сказал, целью является не мой мобильный телефон, а выделенный сервер. Так или иначе, текущий epoll действует на неблокирующие сокеты; AFAIK epoll лучше, чем poll и select с точки зрения производительности. Почему poll лучше, чем epoll (или select)? Любая хорошая статья, чтобы указать там? - person Emanuele; 01.04.2013
comment
@Emanuele: первое предложение руководства по epoll кажется информативным: epoll ... хорошо масштабируется для большого количества просматриваемых fd. Забудьте об этом слове лучше; бессмысленно. Либо примите тот факт, что epoll работает медленно для небольшого количества сокетов, но хорошо масштабируется для большого количества сокетов, либо используйте опрос или выбор. select отслеживает только до FD_SETSIZE сокетов за раз, и это обычно небольшое число. Независимо от выбора, вам необходимо убедиться, что вы используете неблокирующие сокеты. - person autistic; 02.04.2013
comment
Напишите цикл на основе опроса, цикл на основе выбора и цикл на основе epoll. Протестируйте их все с 20-30 клиентами в одном потоке. Посмотрите, какой из них занимает меньше всего времени для проверки событий сокета для этих 20-30 клиентов. Масштабируйте максимальную производительность каждого из ваших ядер. - person autistic; 02.04.2013