Windows, несколько процессов против нескольких потоков - PullRequest
4 голосов
/ 14 октября 2010

Мы должны сделать нашу систему легко масштабируемой, и она была разработана для платформы Windows с использованием VC ++.Скажем, изначально мы хотели бы обрабатывать 100 запросов (из msmq) одновременно.Какой будет лучший подход?Один процесс с 100 потоками или 2 процесса с 50-50 потоками?Какой выигрыш, кроме памяти процесса, при втором подходе.В Windows сначала время ЦП выделяется для обработки, а затем распределяется между потоками для этого процесса, или ОС считает количество потоков для каждого процесса и выделяет ЦП на основе потоков, а не процесса.Мы заметили, что в первом случае загрузка процессора составляет 15-25%, и мы хотим потреблять больше ресурсов процессора.Помните, что мы хотели бы получить оптимальную производительность, поэтому 100 запросов только для примера.Мы также заметили, что если мы увеличим число потоков процесса выше 120, производительность снизится из-за переключения контекста.

Еще один момент;наш продукт уже поддерживает кластеризацию, но мы хотим использовать больше ЦП на одном узле.

Любые предложения будут высоко оценены.

Ответы [ 2 ]

4 голосов
/ 14 октября 2010

Вы не можете обработать больше запросов, чем у вас процессорных ядер. «Быстрые» масштабируемые решения включают настройку пулов потоков, где количество активных (не заблокированных в IO) потоков == количество ядер ЦП. Поэтому создание 100 потоков из-за того, что вы хотите обслуживать 100 запросов MSMQ, не очень хороший дизайн.

Windows имеет механизм пула потоков, называемый IO Completion Ports .

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

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

С другой стороны, механизм IO Completion Port автоматически распределяет события по ожидающим рабочим потокам, но он НЕ удаляет очереди из заданий, если обнаруживает, что текущие «активные» потоки в пуле потоков> = число ядер ЦП.

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

Если ваши службы разрабатываются на c ++, вы можете обнаружить, что сериализованный доступ к куче является большим минусом производительности - хотя в версии 6.1 Windows, похоже, реализована куча с низким уровнем конкуренции, так что это может быть меньше проблем.

Подводя итог - теоретически ваш наибольший прирост производительности был бы за счет проектирования с использованием пулов потоков, управляемых в одном процессе. Но вы сильно зависите от библиотек, которые вы используете, чтобы не сериализовать доступ к критически важным ресурсам, что может быстро лишить вас всех теоретических приростов производительности. Если у вас есть библиотечный код, сериализующий службу с хорошим пулом (как в случае сериализации создания и уничтожения объектов c ++ из-за конфликта в куче), вам нужно изменить использование библиотеки / switch на версию библиотеки с низким уровнем конкуренции или просто масштабировать к нескольким процессам.

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

3 голосов
/ 14 октября 2010

Стандартный подход для Windows - это несколько потоков. Не говоря уже о том, что это всегда ваше лучшее решение, но за каждый поток или процесс приходится платить цену, а в Windows процесс стоит дороже. Что касается планировщика, я не уверен, но вы можете установить приоритет процесса и потоков. Реальным преимуществом потоков является их общее адресное пространство и возможность связи без IPC, однако синхронизация должна быть тщательно поддержана.

Если ваша система уже разработана, как это представляется, вероятно, будет проще реализовать решение с несколькими процессами, особенно если существует вероятность того, что последняя может использовать более одной машины. Так как ваш IPC от 2-х процессов на одной машине может масштабироваться до нескольких машин в общем случае. Большинство попыток массивного распараллеливания проваливаются, потому что вся система не оценивается на наличие узких мест. например, если вы реализуете 100 потоков, которые все записывают в одну и ту же базу данных, вы можете получить небольшую реальную производительность и просто ждать в своей базе данных.

только мой .02

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...