2013-05-31 115 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爲簡單,但信息量大,解釋。 –