Какая разница в производительности между опросом с recv, epoll с recv и простым recv?
У меня есть 4 многоадресных потока, которые я должен слушать, я думаю, у меня есть три варианта. я хочу что лучше
n условия скорости, системный вызов, переключение контекста.
1 poll with recv
2 epoll with recv
3 4 threads with recv
Пожалуйста, предложите мне, что лучше и почему
Не имеет большого значения, какое из трех решений вы выберете, различия не будут огромными. Однако есть один, который позволит вам сохранять системные вызовы (см. В конце).
Для 4 дескрипторов можно предположить, что poll
почти так же быстро, как epoll
, Это будет сильно отличаться для 400 или 4000 дескрипторов, но для 4 дескрипторов, poll
абсолютно приемлемо (хотя вы все еще можете использовать epoll
конечно, просто не ожидай чуда). Важная вещь о epoll
это то, как он масштабируется в зависимости от количества дескрипторов, которые он просматривает, не столько, сколько быстро он отслеживает очень немногие из них.
Опрос (с любой из функций), а затем получение, очевидно, является еще одним системным вызовом, чем получение непосредственно в потоке, хотя в зависимости от точный характер вашей проблемы, это может быть слишком наивным взглядом на это.
Если дейтаграммы с этих четырех адресов многоадресной рассылки могут обрабатываться независимо, вы можете просто запустить один процесс на порт и заблокировать recv
(самое простое решение!), но в противном случае вам нужна какая-то синхронизация, которая может оказаться сложной, если вы не сделали этого раньше, и которая может (будет) включать дополнительные системные вызовы или вращение и, возможно, будет медленнее, чем мультиплексирование. получает.
Количество переключений контекста будет примерно соответствовать количеству системных вызовов независимо от того, есть ли у вас потоки или нет (поскольку в любом случае вы блокируете системные вызовы большую часть времени), если только у вас нет очень загруженной машины с очень небольшим количеством свободных ядер. В этом случае добавление потоков в игру существенно увеличить количество переключений контекста.
Многоадресная передача предполагает UDP, что означает «полные дейтаграммы». Поскольку вы рассматриваете возможность использования epoll
Вы решили, что переносимость не является проблемой. Поэтому вы также можете использовать другой специфичный для Linux системный вызов: recvmmsg
. Это позволяет получать несколько дейтаграмм только с одним системным вызовом. Если бы у вас был только один сокет, вы бы просто заблокировали его, так как он предлагает «получить до N«функциональность. Однако, так как вам все еще нужно мультиплексировать 4 сокета, вы сначала будете использовать epoll
а потом recvmmsg
,