Parallel.For создание потока

Я использую настройку parallel.for:

Parallel.For(0, 4, new ParallelOptions { MaxDegreeOfParallelism = 4 }, j =>

Я ожидаю, что он создаст 4 рабочих потока, однако визуализатор параллелизма показывает, что используются только 3 рабочих потока. я пытался использовать максимальную степень параллелизма и сходства процессоров, однако в каждом сценарии используются только 3 рабочих потока, а не 4. Есть ли очевидный ответ, почему это происходит? ваше здоровье


person Stuart Gordon    schedule 09.11.2013    source источник
comment
Вы уверены, что не забыли поток, в котором запускаете этот код? Это считается одним из этих 4 потоков, но это может быть не рабочий поток (в зависимости от того, как вы решите, что это значит).   -  person svick    schedule 09.11.2013


Ответы (4)


Это так, как написано MaxDegreeOfParallelism, поэтому он не будет превышать это, но и не будет использовать больше, чем считается необходимым.

Вот что написано в MSDN:

По умолчанию For и ForEach будут использовать столько потоков, сколько предоставляет базовый планировщик, поэтому изменение MaxDegreeOfParallelism по умолчанию ограничивает только количество одновременно используемых задач.

person Karl-Johan Sjögren    schedule 09.11.2013
comment
Я так это понял. Однако я сравниваю версию того же алгоритма F #, работающую в тех же условиях. версия F # всегда использует 4 потока, тогда как версия C # всегда использует 3, что я нахожу странным... - person Stuart Gordon; 09.11.2013
comment
Если вы хотите 4 потока, используйте 4 потока. Создавайте задачи внутри обычного цикла For. (Кстати, если этот алгоритм не завершается быстро, вы должны отметить задачи как LongRunning) - person Scott Chamberlain; 09.11.2013
comment
Это все еще не объясняет поведение. Никто не ставит под сомнение законность такого поведения, но почему? - person usr; 09.11.2013
comment
Где код F #, который вы упомянули? Вы наверное разные вещи сравниваете? Даже если вы используете Parallel.For в обоих случаях, будут ли данные одинаковыми? - person Panagiotis Kanavos; 11.11.2013

Это задумано, я не могу вспомнить, где я это читал, но он использует пул потоков внизу, и он просто выполняет задачи, поскольку для этого есть мощность процессора. Хотя звучит странно, что есть разница между C# и F#.

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

Если вы хотите заставить его использовать 4, вы можете написать свой собственный планировщик.

person Nickolai Nielsen    schedule 09.11.2013

Как уже говорилось, вы можете указать только максимальное, а не фактическое количество потоков. Если у вас есть четыре доступных ядра и рабочая нагрузка нетривиальна, все четыре будут работать параллельно, поскольку поток, из которого вы запустили For, также используется для выполнения рабочих элементов.

Кроме того, Parallel.For может разделить ваш входной диапазон. Этого, вероятно, не будет для четырех элементов, но если вас это беспокоит, вы можете запланировать 4 элемента одновременно с помощью Parallel.Invoke().

person Community    schedule 09.11.2013

Parralel.For понятия не имеет, сколько раздражений вы ему доставите, он гибкий, он обрабатывает очереди потоков и во время выполнения решает, какое доступное ядро ​​​​получает определенный рабочий поток от threadque. Ядро может быть недоступно, так как это не только ваш код, работающий на компьютере с Windows. Или ядро ​​все еще может быть занято предыдущей рабочей нагрузкой, которую вы ему дали.

Здесь более подробная информация http://reedcopsey.com/2010/01/26/parallelism-in-net-part-5-partitioning-of-work/

person Peter    schedule 30.03.2016