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

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

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

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

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

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

Ответ 1

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

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

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

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

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