.NET 4 Parallel.ForEach и PLINQ: могут ли они перегрузить пул потоков и снизить производительность приложения? - PullRequest
8 голосов
/ 25 марта 2012

Чем больше я использую Parallel.ForEach и PLINQ в своем коде, тем больше я получаю откликов и повторений кода.Поэтому мне интересно, есть ли причина, по которой я НЕ должен использовать PLINQ, в крайнем случае, для каждого оператора LINQ?Может ли среда выполнения не быть достаточно умной, чтобы начать порождать так много потоков (или потреблять столько потоков из пула потоков), что производительность приложения будет снижаться, а не улучшаться?Тот же вопрос относится к параллельной библиотеке.

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

ОБНОВЛЕНИЕ: пожалуйстаПредположим, что аппаратное обеспечение достаточно хорошо, чтобы удовлетворить предварительные условия использования многопоточности.

Ответы [ 3 ]

4 голосов
/ 25 марта 2012

Все сводится к двум вещам:

  1. Требуется ли дополнительная работа для разделения коллекции и синхронизации потоков больше, чем прирост производительности по сравнению с обычным foreach?

  2. Будут ли все потоки использовать общий ресурс, который станет узким местом?

Примером второго случая является Parallel.ForEach над результатами оператора Linq to Sql. В этом случае, если ваши результаты поступают из БД очень медленно, каждый поток может тратить больше времени на ожидание обработки данных, чем на самом деле.

См .: http://msdn.microsoft.com/en-us/library/dd997392.aspx

3 голосов
/ 25 марта 2012

Чтобы установить количество рабочих потоков, которые вы можете использовать .WithDegreeOfParallelism (N)

например

var query = from item in source.AsParallel().WithDegreeOfParallelism(2)
            where Compute(item) > 42
            select item;

См. http://msdn.microsoft.com/en-us/library/dd997425.aspx

2 голосов
/ 25 марта 2012

Когда углубляешься в вопросы производительности, я думаю, что лучшее, что нужно сделать - это ... измерить, измерить и измеритьДаже если кто-то ответит, что PLINK великолепен и повысит производительность вашего приложения, поверите ли вы этому, не проверяя его с помощью профилирования?Хотя общие ответы могут существовать, вы не можете сэкономить усилия для измерения производительности в вашем конкретном случае.Общая производительность зависит от многих вещей, и может случиться так, что PLINK помогает в одном случае, но не в другом.Мой личный опыт работы с PLINK заключается в том, что после каждого запроса LINQ в PLINK время отклика становится намного лучше, когда нагрузка мала, и нет разницы, когда нагрузка достигает своего максимума.Но я могу представить себе случай, когда PLINK ухудшает общую производительность при огромной нагрузке.Нужно проверить это для вашего собственного конкретного случая.Ну ... и если вы хотите убедить других людей, что вы идете по правильному пути, что еще может быть лучше результатов измерений?

...