Я предполагаю, что для # 2 вы планируете вручную связать свои сокеты с IOCP, который, по вашему мнению, является «лучшим» на основе некоторой меры «добродетели» в момент принятия сокета?И что каким-то образом эта мера «добродетели» будет сохраняться на протяжении всего срока службы сокета?
С IOCP использовался «стандартный» способ, т. Е. Ваш вариант № 1, ядро решает, как лучше использовать потоки, которые вы используете.иметь и позволяет больше работать, если любой из них заблокировать.С вашим методом, если вы как-то решите, как распределить работу, вы получите больше потоков, чем с опцией 1.
Ваша опция # 2 также не позволяет использовать AcceptEx()
для перекрытияпринимает, и это более эффективно, чем использование обычного цикла принятия, когда вы удаляете поток (и результирующее переключение контекста и потенциальную конкуренцию) со сцены.
Ваша аналогия нарушается;на самом деле это скорее случай наличия 1 очереди с кассирами Х-банка, когда вы присоединяетесь к очереди и знаете, что вас будут видеть в эффективном порядке, в отличие от каждого кассира, имеющего свою очередь, и вам придется угадывать, что очередь, к которой вы присоединяетесьне содержит целую группу людей, которые хотят открыть новые учетные записи, а рядом с вами находится целая группа людей, которые хотят только внести некоторые платежи. Единая очередь гарантирует, что вы будете обрабатываться эффективно.
Я думаю, что вы не уверены в MEM_COMMIT
.Это не означает, что память не находится в файле подкачки и не будет выгружена.Обычная причина использования VirtualAlloc
для перекрывающихся буферов состоит в том, чтобы обеспечить выравнивание по границам страниц и, таким образом, уменьшить количество страниц, заблокированных для ввода-вывода (буфер размера страницы может быть размещен на границе страницы, поэтому занимает только одну страницувместо того, чтобы охватывать два из-за того, что менеджер памяти решил использовать блок, который не начинается на границе страницы).
В общем, я думаю, что вы пытаетесь оптимизировать что-то с опережением графика.Получите эффективный сервер, работающий с использованием IOCP сначала обычным способом, а затем профилируйте его.Я серьезно сомневаюсь, что вам даже придется беспокоиться о сборке версии №2 ... Аналогичным образом, используйте new
, чтобы выделить ваши буферы для начала, а затем переключитесь на дополнительную сложность VirtualAlloc()
, когда вы обнаружите, что ваш серверпроисходит сбой из-за ENOBUFS
, и вы уверены, что это связано с лимитом заблокированных страниц ввода-вывода, а не с отсутствием невыгружаемого пула (вы действительно понимаете, что для VirtualAlloc()
нужно выделять фрагменты размером «гранулярность выделения»?).
В любом случае, у меня есть бесплатный серверный фреймворк IOCP, доступный здесь: http://www.serverframework.com/products---the-free-framework.html, который может помочь вам начать работу.
Отредактировано: Комплекспредлагаемая версия может быть полезна в некоторых архитектурах NUMA, где вы используете группирование сетевых адаптеров, чтобы коммутатор распределял трафик между несколькими сетевыми картами, связывал каждый сетевой адаптер с различным физическим процессором, а затем связывал потоки IOCP с одним и тем же процессором.Затем вы распределяете память от этого узла NUMA и эффективно заставляете свой сетевой коммутатор распределять нагрузку на ваши соединения между вашими узлами NUMA.Я бы по-прежнему предположил, что лучше, имхо, получить работающий сервер, который можно профилировать, используя «нормальный» метод использования IOCP в первую очередь, и только после того, как вы узнаете, что проблемы с несколькими узлами NUMA на самом деле влияют на вашу производительность в сторону более сложныхархитектура ...