2013-05-31 112 views
4

我有一个的Parallel.For和常规的for循环做一些简单的算术,只是基准的Parallel.For的Parallel.For,相较于

我的结论是,常规的是我的睿i5笔记本处理器速度更快。

这是我的代码

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      int Iterations = int.MaxValue/1000; 
      DateTime StartTime = DateTime.MinValue; 
      DateTime EndTime = DateTime.MinValue; 

      StartTime = DateTime.Now; 
      Parallel.For(0, Iterations, i => 
      { 
       OperationDoWork(i); 
      }); 
      EndTime = DateTime.Now; 
      Console.WriteLine(EndTime.Subtract(StartTime).ToString()); 

      StartTime = DateTime.Now; 
      for (int i = 0; i < Iterations; i++) 
      { 
       OperationDoWork(i); 
      } 
      EndTime = DateTime.Now; 
      Console.WriteLine(EndTime.Subtract(StartTime).ToString()); 

      StartTime = DateTime.Now; 
      Parallel.For(0, Iterations, i => 
      { 
       OperationDoWork(i); 
      }); 
      EndTime = DateTime.Now; 
      Console.WriteLine(EndTime.Subtract(StartTime).ToString()); 

      StartTime = DateTime.Now; 
      for (int i = 0; i < Iterations; i++) 
      { 
       OperationDoWork(i); 
      } 
      EndTime = DateTime.Now; 
      Console.WriteLine(EndTime.Subtract(StartTime).ToString()); 
     } 

     private static void OperationDoWork(int i) 
     { 
      int a = 0; 
      a += i; 
      i = a; 
      a *= 2; 
      a = a * a; 
      a = i; 
     } 
    } 
} 

这些是我的结果。哪个重复没有多大变化:

00:00:03.9062234 
00:00:01.7971028 
00:00:03.2231844 
00:00:01.7781017 

那么为什么要使用Parallel.For?

+0

如果内存服务,'Parallel.For'并不总是将工作分解成多个线程,它可能在单个线程上运行整个事情。您可能正在查看在轻量级作品上使用“并行”方法所涉及的开销,因为在线程上编组工作成本高昂。 –

+3

您在每次迭代中所做的实际工作量并不多,因此创建和管理和整合线程的成本远高于并行处理获得的收益。 'Parallel.For'只会在你每轮耗费更多时间的情况下更快。 – Corak

+0

[看看这个最近的答案,我做了一些详细的时间安排](http://stackoverflow.com/a/16822242/106159)。 'Parallel.For()'适用于小型循环体,如果你使用'Partitioner',就像我在那个答案中那样。 –

回答

7

其中一个最常见的错误就是,当初次尝试多线程时,相信多线程是一个Free Lunch

事实上,将您的操作拆分为多个可以并行运行的小操作需要一些额外的时间。如果不同步,你的任务可能会花更多的时间,等待其他任务释放他们的锁。

因此,并行是不值得的时间/麻烦,当每个任务要做的工作很少,这是OperationDoWork的情况。

编辑:

考虑尝试了这一点:

private static void OperationDoWork(int i) 
    { 
     double a = 101.1D * i; 
     for (int k = 0; k < 100; k++) 
      a = Math.Pow(a, a); 
    } 

根据我的基准,for将平均5.7秒,而Parallel.For将3.05秒我的Core 2 Duo CPU(加速==〜1.87 )。
在我的Quadcore i7上,for的平均值为5.1秒,Parallel.For的平均值为1.38秒(加速==〜3.7)。

这个修改后的代码很好地适应可用物理内核的数量。 Q.E.D.

+0

+1免费Luch –

9

并行处理有组织开销。想想它有100个任务和10个人来完成。要让10个人为你工作并不容易,除了实际上做了这100个任务之外,还要组织谁做什么花费时间。

所以,如果你想要做并行的东西,请确保它是的工作量组织相比实际工作量是有意义的做并行这么小这么多的工作。

+2

非常好的解释。 “我自己做得更快!”这可能是每个人都至少有过一次“团队合作”的经历。 – Corak

+0

+ +1为简单,但信息量大,解释。 –