Сервер TCP w/boost:: asio, масштабируемость пула потоков и стекированных сопрограмм

Я создаю демона на основе TCP для предварительной или последующей обработки HTTP-запросов. Клиенты будут подключаться к Apache HTTPD (или IIS), а настраиваемый модуль Apache/IIS будет перенаправлять запросы на мой демон TCP для дальнейшей обработки. Моему демону необходимо будет увеличить (но не выйти) для обработки значительного трафика, и большинство запросов будут небольшими и недолговечными. Демон будет построен на С++ и должен быть кросс-платформенным.

В настоящее время я смотрю на библиотеки boost asio, которые кажутся естественными. Тем не менее, у меня возникли проблемы с пониманием достоинств шаблона пустых пакетов coroutines vs thread. В частности, я смотрю пример HTTP-сервера №3 и пример HTTP-сервера №4 здесь: http://www.boost.org/doc/libs/1_49_0/doc/html/boost_asio/examples.html

Несмотря на всю мою работу в Google, я не могу полностью понять достоинства сервера без стекирования и как он будет работать относительно сервера пула потоков в многоядерной системе.

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

Изменить. Еще одна случайная мысль/проблема для обсуждения: Пример HTTP-сервера Boost HTTP # 4 описывается как "однопоточный HTTP-сервер, реализованный с использованием стекированных сопрограмм". ОК, так что он полностью однопоточный (правда? Даже после того, как родительский процесс "вилки" для ребенка? См. Server.cpp в примере № 4)... будет ли единственный поток стать узким местом в многоядерной системе? Я предполагаю, что любые операции блокировки будут препятствовать выполнению всех других запросов. Если это действительно так, чтобы максимизировать пропускную способность, я думаю о async-событии на основе coroutine-данных, пул потоков для моих внутренних задач блокировки (для использования нескольких ядер), а затем механизм асинхронного отправки и закрытия соединения. Опять же, масштабируемость имеет решающее значение. Любые мысли?

Ответ 1

Недавно я посмотрел на масштабируемость boost.asio на многоядерных машинах. Основной вывод заключается в том, что он вводит накладные расходы, блокировку конкуренции и дополнительные контекстные переключатели (по крайней мере, в Linux), см. Некоторые из моих сообщений в блогах по этим темам:

Я также начал поток в списке рассылки asio, чтобы проверить, что я не пропустил ничего очевидного, см. http://comments.gmane.org/gmane.comp.lib.boost.asio.user/5133

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

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

Изменить: просто для того, чтобы разглядеть материал стекированных сопрограмм: по существу, это просто какой-то синтаксический сахар, чтобы асинхронный API выглядел немного более похожим на последовательные/блокирующие вызовы.

Ответ 2

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

Если вы хотите получить эвристическое предположение, считайте, что использование n потоков с размером стека S каждый всегда принимает nS-байты, но большую часть пространства стека использует каждый поток. Если это подтолкнет вас к границе страницы, это может значительно снизить производительность.