2013-02-05 65 views
0

網上有人說以下C#代碼不能轉換爲一些Parallel.for(對於多核系統)是否正確?如果是,是否有更好的方法來進一步優化它。感謝TPL和Parallel.for

  for (int i = 0; i < 4; i++) 
      { 
       var tmp = i; 
       tasks[i] = Task.Factory.StartNew(() => Console.WriteLine(tmp)); 
      } 
+3

你想用這個'tasks'數組做什麼?這是你的一組實際任務,只需要向控制檯寫4次?至於4次迭代,您可能會因開始新線程而承受更多的開銷,而不是從並行完成的工作中獲得收益。 –

+0

只是FYI,Parallel.For有很多開銷,所以除非你真的測量過並且發現速度更快,或者需要內置節流,否則我建議你循環使用Task.Run來完成工作你在做, –

回答

1

好了,你沒有Tast.WaitAll(tasks)在年底,這Parallel.For願意爲你做,這樣你就不太做什麼Parallel.For在做什麼(除非你有沒有把這些代碼在你的問題。如果是這樣,則下一行是你的代碼是什麼樣子的循環的Parallel.For)

Parallel.For(0,4, (i) => Console.WriteLine(i)); 

除此之外,我不明白爲什麼你不能將其轉換爲的Parallel.For。這個人給了什麼理由不能轉換它?

+0

是的,我有TaskWaitAll,但我沒有發佈所有的代碼。謝謝你的代碼行! – user2023152

+0

它沒有工作。它在運行過程中編譯得很好但錯誤太多。 – user2023152

+0

你得到了什麼錯誤? –

0

因爲我們沒有外部循環代碼,所以我在黑暗中進行了刺探。如果你只是衡量整體平均運行時你並不需要保存的任務,你可以使用這樣的測量串行和並行版本:

var iterations = 100; 
var stopwatch = new Stopwatch(); 

// Run Serial version 
stopwatch.Start();  
for(int i = 0; i < iterations; i++) 
{ 
    for (int i = 0; i < 4; i++) 
    { 
     Console.WriteLine(tmp); 
    } 
} 

stopwatch.Stop(); 
var serialTime = stopwatch.ElapsedMilliseconds; 
stopwatch.Reset(); 

// Run parallel version 
stopwatch.Start(); 

for(int i = 0; i < iterations; i++) 
{ 
    Parallel.For(0,4, (i) => Console.WriteLine(i));  
} 

stopwatch.Stop(); 

var parallelTime = stopwatch.ElapsedMilliseconds; 

Console.WriteLine("Serial took : {0}ms", serialTime/(double)iterations); 
Console.WriteLine("Parallel took: {0}ms", parallelTime/(double)iterations); 

這可能不是用於測量由於加速很大的考驗工作量很輕。你可以嘗試用更多的開銷或類似Thread.Sleep來模擬更多的工作。另請參閱我在This StackOverflow Question上的答案,瞭解如何測量C#中的Amdahl法則加速。

+0

謝謝。這是一個很好的例子,但是其他性能原因需要完成這些任務。有沒有辦法通過電子郵件聯繫,所以我可以給你發送兩個CPU利用率圖,希望你能解釋發生了什麼? – user2023152

+2

最好更新您的問題並上傳圖表,以便每個人都能受益。 StackOverflow還有一個開放的聊天工具(這是公開的),這樣每個人都可以受益 - 這就是本網站的重點。 –

0

首先,有關錯誤你報:

未處理的異常:System.AggregateException:一個或多個erroros發生。 System.ArgumentExcpetion:任務陣列inclue至少一個空元素paraemeter名稱:任務

的錯誤是很清楚,它是由您的通話Task.WaitAll提出 - 它說,在你的tasks陣列任務插槽之一是空值。

其次,Console.WriteLine衡量績效不好的原因有兩個:

  1. 工作量太亮:我猜測,設置開銷將大大超過實際工作;
  2. Console.WriteLine是同步的 - 意味着所有的任務將開始,然後立即同步 - 這是使用地圖縮小API絕對不適合的情況。只需設計一個真正的計算工作負載(例如計算素數);