Доброго дня
Свой проект основываю на epoll (его используют и asio, и libevent). В соответствие с рекомендациям в инете реализовал следующий принцип работы:
Listener - поток, выполняющий вызовы bind() и listen() и слушающий входящий сокет в ожидании входящих соединений. Когда приходит новое соединение, этот поток делает вызов accept() на слушающем сокете и отправляет полученный сокет соединения к I/O-workers.
I/O-Worker(s) - один или несколько потоков, получающих соединения от Listener и добавляющих их в epoll.
Data Processing Worker(s) - один или несколько потоков для получения и отправки данных для I/O-workers и выполняющих обработку данных.
Таким образом в приложении:
- первый поток: главный поток (QApplication, логи, настройки и т.п.);
- второй поток: Listener (поднимает слушающий сокет, принимает входящие соединения);
- третий поток: I/O-Worker (принимает запросы с сокетов, отправляет ответы клиентам);
- четвёртый поток: Data Processing Worker (собственно занимается парсингом запросов, их выполнением, отдачей данных ответов назад в I/O-Worker).
В проекте я реализовал поддержку одновременной работы нескольких I/O-Worker и нескольких Data Processing Worker. И вопрос заключается в определении их количества для получения максимальной производительности. Эмпирическим путём на своей восьми-ядерной машине вычислил, что самое эффективное:
I/O-Worker - 4 потока;
Data Processing Worker - тоже 4 потока;
Но это у меня, а как дело будет на другом железе - неясно. Да и просто хотелось бы привязаться к какой-либо формуле. В моей ситуации 4х4 присутствуют ведь ещё два потока - главный и Listener. Получается, что 10 потоков на 8-ми ядерной машине. В общем, если у кого есть опыт в данном вопросе, поделитесь, пожалуйста, своими соображениями. Спасибо.