Задача параллельной библиотеки и несколько параллельных задач - PullRequest
2 голосов
/ 31 марта 2011

Как TPL обрабатывает несколько параллельных вызовов?

Пример: я хочу обрабатывать две не связанные коллекции параллельно. (предположим, что обработка одного предмета в каждой коллекции занимает очень много времени)

В настоящее время я делаю это так:

Parallel.Invoke(() => Parallel.ForEach(collection1,...),
                () => Parallel.ForEach(collection2,...))

Это работает, но мне любопытно, как планировщик TPL будет обрабатывать 3 отдельных вызова.

Должен ли я сделать это по-другому?

1 Ответ

2 голосов
/ 31 марта 2011

2 важных вещи в первую очередь:

  • Если у вас есть длительные итерации в рабочей нагрузке Parallel.For / Parallel.ForEach (или любой тип блокировки в делегате цикла), вам следуетвсегда указывайте уровень параллелизма, используя ParallelOptions.MaxDegreeOfParallelism.Это связано с тем, что реализации параллельных циклов были оптимизированы для более мелкозернистых рабочих нагрузок, и они могут в конечном итоге внедрить дополнительные рабочие потоки, когда сталкиваются с длительными итерациями.

  • Запуская одновременные параллельные циклы, вы ужезаставляя 2 цикла конкурировать за ресурсы процессора.Поэтому, даже если у вас не было длинных итераций, было бы разумно явно распределить их по нагрузке, ограничив MaxDOP каждого цикла (практически я бы использовал Environment.ProcessorCount / 2 для каждой)

Чтобы ответить на ваши первоначальные вопросы:

... 3 отдельных вызова ...

Да, TPL будет обрабатывать 3 или болееотдельная параллель. вызывает просто отлично.Он даже оптимизирован, чтобы не тратить потоки в сценарии с вложенным параллелизмом, как этот.

Должен ли я сделать это по-другому?

Как минимумВы должны использовать MaxDOP, как я объяснил выше.Но вы можете выбрать другую стратегию DOP, основанную на них:

  • Нужно ли приблизительно одинаковое количество работ для коллекций?
  • Есть ли у вас какие-либо блокировки в делегатах цикла?
...