为什么这个并行代码比它的类似非并行版本慢?

我有以下代码(从LINQPad复制)。 显然,看起来我不理解TPL如何工作或代码是垃圾,为什么并行版本运行速度比非并行版本慢?

for (int i = 0; i < 100; i++) { ParallelOptions ops = new ParallelOptions(); ops.MaxDegreeOfParallelism = Environment.ProcessorCount; var watch = Stopwatch.StartNew(); Parallel.ForEach(Enumerable.Range(1, 10000000), ops, x => { int y = x + 1; }); watch.Stop(); Console.WriteLine("Parallel: {0}", watch.Elapsed.TotalSeconds); watch = Stopwatch.StartNew(); foreach (var x in Enumerable.Range(1, 10000000)) { int y = x + 1; } watch.Stop(); Console.WriteLine("Non-parallel: {0}\n", watch.Elapsed.TotalSeconds); } 

前10个结果:

平行:0.1991644非平行:0.0466178

平行:0.1723428非平行:0.0447134

平行:0.1141791非平行:0.0444557

平行:0.1758878非平行:0.0444636

平行:0.1687637非平行:0.0444338

平行:0.1677679非平行:0.0445771

平行:0.1191462非平行:0.0446116

平行:0.1702483非平行:0.0454863

平行:0.1143605非平行:0.0451731

平行:0.2155218非平行:0.0450392

那么,您可以获得的最佳答案是运行一个分析器工具并测量代码的运行情况。 但我有根据的猜测是你的并行代码较慢,因为你的代码非常简单,启动线程并在它们之间切换会增加成本,以至于计算速度的任何优势都可以忽略不计。

但是尝试进行一些实质性的计算,最终你将拥有并行执行优势。 你的代码太简单了。 不以这种方式加载现代CPU。

由于我无法将其添加为评论,因此我将添加另一个答案来发布修改后的代码。 @ixSci在他的回答中说的似乎是正确的。 我在执行速度非常快的并行代码体中执行了一个简单的操作,但缓慢来自于线程之间的上下文切换花费了大量时间这一事实? 当我将代码更改为hibernate一段时间而不是将int值增加1时,并行代码大约为4(我的CPU中的核心数)比非并行版本快。

 for (int i = 0; i < 100; i++) { ParallelOptions ops = new ParallelOptions(); ops.MaxDegreeOfParallelism = Environment.ProcessorCount; var partitioner = Partitioner.Create(Enumerable.Range(1, 5000)); var watch = Stopwatch.StartNew(); Parallel.ForEach(partitioner, ops, x => { Thread.Sleep(1); }); watch.Stop(); Console.WriteLine("Parallel: {0}", watch.Elapsed.TotalSeconds); watch = Stopwatch.StartNew(); foreach (var x in Enumerable.Range(1, 5000)) { Thread.Sleep(1); } watch.Stop(); Console.WriteLine("Non-parallel: {0}\n", watch.Elapsed.TotalSeconds); } 

前10个结果:

平行:1.2887589非平行:5.0020569

平行:1.277047非平行:5.0011116

平行:1.2790631非平行:5.0001498

平行:1.2770644非平行:5.0052016

平行:1.2770013非平行:5.0021479

平行:1.2770031非平行:5.0001927

平行:1.2799937非平行:5.0062141

平行:1.2819909非平行:5.0171945

平行:1.2780496非平行:5.0071667

平行:1.2821714非平行:5.0082108

平行:1.2777875非平行:5.0152099