Подтвердить что ты не робот

С одним файловым дескриптором, есть ли разница в производительности между select, poll и epoll и...?

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

В и... средства также входят pselect и ppoll..

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

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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