MaxDegreeOfParallelism做什么?

我正在使用Parallel.ForEach,我正在做一些数据库更新,现在没有设置MaxDegreeOfParallelism,一个双核心处理器机器导致SQL客户端超时,其他四核心处理器机器不知何故超时。

现在,我无法控制运行代码的处理器内核的types,但是有些设置可以通过MaxDegreeOfParallelism更改,这样可能会同时运行更less的操作,并且不会导致超时?

我可以增加超时,但它不是一个好的解决scheme,如果在较低的CPU上,我可以同时处理较less的操作,这将减less对CPU的负载。

好吧,我也读过所有其他post和MSDN,但将MaxDegreeOfParallelism设置为较低的值,使我的四核心机器遭受?

例如,有没有办法做,如果CPU有两个核心,那么使用20,如果CPU有四个核心,然后40?

答案是它是整个并行操作的上限,而不pipe核的数量如何。

所以,即使你不使用CPU,因为你正在等待IO或锁,没有额外的任务将并行运行,只有你指定的最大值。

为了找出这个问题,我写了这段testing代码。 在那里有一个人造锁以刺激TPL使用更多的线程。 当您的代码正在等待IO或数据库时,也会发生同样的情况。

class Program { static void Main(string[] args) { var locker = new Object(); int count = 0; Parallel.For (0 , 1000 , new ParallelOptions { MaxDegreeOfParallelism = 2 } , (i) => { Interlocked.Increment(ref count); lock (locker) { Console.WriteLine("Number of active threads:" + count); Thread.Sleep(10); } Interlocked.Decrement(ref count); } ); } } 

如果我不指定MaxDegreeOfParallelism,则控制台日志logging显示最多可同时运行大约8个任务。 喜欢这个:

 Number of active threads:6 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:6 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 Number of active threads:7 

它开始降低,随着时间的推移而增加,最后它试图同时运行8次。

如果我把它限制在一些任意的值(比如说2),我会得到

 Number of active threads:2 Number of active threads:1 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 Number of active threads:2 

哦,这是在一个quadcore机器上。

例如,有没有办法做,如果CPU有两个核心,那么使用20,如果CPU有四个核心,然后40?

您可以这样做,以取决于CPU核心数量的并行性:

 var options = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount * 10 }; Parallel.ForEach(sourceCollection, options, sourceItem => { // do something }); 

然而,较新的CPU倾向于使用超线程来模拟额外的内核。 所以,如果你有一个四核处理器,那么Environment.ProcessorCount可能会报告为8核心。 我发现如果你设置了模拟内核的并行性,那么它实际上会减慢其他线程,比如UI线程。

因此,虽然操作速度会更快,但在这段时间内,应用程序用户界面可能会经历显着的延迟。 将Environment.ProcessorCount除以2似乎达到了相同的处理速度,同时仍然保持CPU线程可用的CPU。

这听起来像是你并行运行的代码是死锁,这意味着除非你能find并解决这个问题,否则你就不应该并行化。

它设置线程的数量并行运行…