.NET сокращает количество параллельных потоков при повторяющихся запусках

Есть ли веская причина для .NET сократить количество параллельных потоков с течением времени?

Я выполняю расчеты во многих проходах, которые занимают дни (каждый проход занимает ~ 1 час). Задачи представляют собой чистые вычисления данных в памяти (чтение с диска). Я использую Parallel.For и Parallel.ForEach несколько мест, как для основной задачи, так и внутри задачи. Все повторяется за много проходов. Экземпляры класса удаляются (профилировщик памяти не показывает никаких проблем с течением времени) правильно для каждого прохода, и создается новый экземпляр. Он повторяет 100% одну и ту же задачу в каждом проходе, за исключением того, что некоторые числа в математике изменяются (одинаковое количество итераций каждый раз, один и тот же набор данных).

Компьютер имеет шесть ядер, и приложение начинает работу, используя их все. Через некоторое время он использует 5, затем 4, затем 3, затем 2. Глядя на параллельные стеки (Отладка-> Окно-> Параллельные стеки), он подтверждает, что работает только это количество.

Почему .NET не использует максимальное количество потоков при каждом проходе? Регулирует ли он потоки в зависимости от использования ЦП?

Советы по отладке? Могу ли я принудительно использовать количество потоков?


person Tedd Hansen    schedule 11.08.2011    source источник
comment
@Skomski: это предложение, а не принудительное. @Tedd: Чтобы заставить это, вы должны использовать PLINQ и .WithDegreeOfParallelism(value) или явно создавать потоки самостоятельно.   -  person Marc    schedule 11.08.2011
comment
Максимальное количество потоков: msdn.microsoft.com /en-us/библиотека/   -  person Skomski    schedule 11.08.2011


Ответы (1)


Я считаю, что эта статья о параллелизме ThreadPool должна дать некоторые подсказки.

Задачи, созданные методами Parallel, в конечном итоге будут выполняться ThreadPool. Идеальное количество потоков для ThreadPool зависит от типа выполняемых задач. Если задачи много блокируют и не имеют большого количества конфликтов, большее количество потоков приведет к более высокой пропускной способности. Для задач с небольшой блокировкой и высокой конкуренцией за ограниченные ресурсы меньшее количество потоков приведет к более высокой пропускной способности.

Благодаря этому свойству ThreadPool в .NET 4 реализует алгоритм «восхождения в гору», в котором он настраивает количество потоков, которые выполняет ThreadPool, и реагирует на основе измеренной пропускной способности.

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

Что касается принуждения ThreadPool к использованию определенного количества потоков, я не думаю, что это возможно. Существует ThreadPool.SetMinThreads, но он никогда не работал для меня. Как правило, .NET просто игнорирует эти значения и использует любое количество потоков, которое захочет.

person RandomEngy    schedule 11.08.2011