MaxDegreeOfParallelism = Environment.ProcessorCount减慢了CPU的执行时间
我有以下程序(我从http://blogs.msdn.com/b/csharpfaq/archive/2010/06/01/parallel-programming-in-net-framework-4-getting-started.aspx获得 )使用Parallel.For循环拆分任务
class Program { static void Main(string[] args) { var watch = Stopwatch.StartNew(); Parallel.For(2, 20, (i) => { var result = SumRootN(i); Console.WriteLine("root {0} : {1} ", i, result); }); Console.WriteLine(watch.ElapsedMilliseconds); Console.ReadLine(); } public static double SumRootN(int root) { double result = 0; for (int i = 1; i < 10000000; i++) { result += Math.Exp(Math.Log(i) / root); } return result; } }
当我多次运行此测试时,我会得到以下时间:
1992年,2140年,1783年,1863年等等
我的第一个问题是, 为什么时代总是不同? 我每次都在进行完全相同的计算,但每次时间都不同。
现在,当我添加以下代码以使用我CPU上的所有可用处理器时:
var parallelOptions = new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount (On my CPU this is 8) }; Parallel.For(2, 20, parallelOptions, (i) => { var result = SumRootN(i); Console.WriteLine("root {0} : {1} ", i, result); });
我注意到执行时间实际上增加了!! 现在是时候了:
2192,3192,2603,2245毫秒等
为什么这会导致时间增加? 我用错了吗?
来自http://msdn.microsoft.com/en-us/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism(v=vs.110).aspx
默认情况下,
For
和ForEach
将使用底层调度程序提供的许multithreading。 从默认值更改MaxDegreeOfParallelism仅限制将使用多少并发任务。
这意味着将MaxDegreeOfParallelism
设置为处理器数实际上会限制Parallel.For
循环的容量,以便为工作负载使用最佳线程数。 例如,我有一个迁移作业,在大约600次长时间运行的代码迭代中使用了近60个线程,远远超过了您尝试设置的每个处理器限制的1个线程 。
只有在明确需要阻止执行超过给定数量的线程时,才应使用MaxDegreeOfParallelism
或ThreadPool.SetMaxThreads
。 例如,如果使用Access数据库,我会将其设置为64,因为这是Access可以为单个进程处理的最大并发连接数。