С одним дескриптором файла, есть ли разница в производительности между select, poll и epoll и ...? - PullRequest
13 голосов
/ 13 апреля 2011

Название действительно говорит само за себя.

Средства and ... также включают pselect и ppoll.

Серверный проект, над которым я работаю, в основном состоит из нескольких потоков. каждый Поток обрабатывает один или несколько сеансов. Все темы идентичны. Протокол заботится о том, какой поток будет принимать сеанс.

Я использую внутренний класс сокетов, который оборачивает вещи. Интересной точкой является вызов checkread, который вызывает poll (linux) или select (windows).

В итоге каждый поток в настоящее время вызывает опрос для одного сокета. Из того, что я могу сказать, использование epoll было бы полезным только в том случае, если этот поток просматривал несколько сокетов, например, что вы получите, скажем, HTTP-сервер. Это не то, что я делаю в моем случае. И класс обрабатывает только один сокет одновременно.

На страницах руководства для epoll есть несколько кратких обсуждений о запуске краев и уровней. Я не совсем уверен, что это значит. В классе сокетов я вижу оптимизацию в части окна кода, которая сокращает вызов select с помощью ioctlsocket & FIONREAD, чтобы проверить, есть ли какие-либо данные. Интересно, вернется ли это> 0, даже если полный пакет UDP не прибыл во время вызова. Это то, что запуск по фронту в epoll?

В некоторых элементарных тестах я также не вижу заметной разницы между использованием select и poll.

Я вижу, что использование ppoll может быть полезным, хотя и из-за большей точности в тайм-ауте. Есть мысли?

И да, я пытаюсь оптимизировать пропускную способность для сеанса, который получает большое количество данных. Сервер больше связан с сетью и диском, чем с процессором.

Ответы [ 3 ]

7 голосов
/ 26 апреля 2011

Основное различие между epoll и select или poll заключается в том, что epoll масштабируется намного лучше при запуске в одном потоке. Я не знаю, как это можно сравнить с использованием многопоточного сервера с использованием select или poll. Посмотрите на это http://monkey.org/~provos/libevent/libevent-benchmark2.jpg

Причина этого (насколько я могу судить) состоит в том, что когда вы используете select или poll, вы должны пройти через все подключенные сокеты, чтобы определить, какие из них имеют данные для чтения. Когда вы используете epoll, он хранит отдельный массив, который содержит ссылки только на сокеты, которые имеют данные для чтения. Это экономит много циклов цикла, и чем больше разъемов подключено, тем заметнее становится разница.

Еще одна вещь, на которую стоит обратить внимание, если производительность когда-либо станет основной проблемой, - это io порты завершения (только для windows) и kqueue (только для FreeBSD). Также важно помнить, что epoll - это только linux. В большинстве случаев select или poll будут работать очень хорошо.

В случае одного файлового дескриптора, select и poll более эффективны, чем epoll , поскольку они намного проще. (у epoll есть некоторые издержки, которые бесполезны только с одним сокетом)

4 голосов
/ 03 февраля 2015

По ссылке: http://www.intelliproject.net/articles/showArticle/index/io_multiplexing.

Если вы используете только один дескриптор:

  • select: 201 микросекунда.
  • poll: 159 микросекунд.
  • epoll: 176 микросекунд.

Кажется, poll будет лучшим решением в такой ситуации.

0 голосов
/ 13 апреля 2011

Если у вас только один сокет, какой смысл опрашивать в первую очередь?Разве лучшая производительность не была бы при использовании блокировки чтения / записи?

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

Уровень / край запуска .Предположим, вы отслеживаете сигнал, для простоты скажем, какое-то напряжение в линииЗапуск по фронту означает, что что-то срабатывает, когда напряжение превышает или ниже определенного предела.Запуск по уровню означает, что считается, что что-то находится в сработавшем состоянии, пока напряжение превышает / ниже предела.То есть, запуск по фронту срабатывает, когда происходит какое-то событие (пересекает некоторый порог), запуск по уровню отражает состояние некоторой «вещи» (в данном случае, напряжения).

Для возврата к сетевому программированию и запуска по фронтуСистема может быть той, где вы получаете какой-то сигнал при получении пакета.Если вы не обрабатываете событие, то сигнал теряется.Система, запускаемая по уровню, OTOH, это что-то вроде вопроса «есть ли в буфере данные для меня?»;если вы не обработаете событие и не спросите снова, данные все еще будут там ждать вас.

...