2012-04-04 147 views
0

我寫了Wpf代碼來使用隨機變量生成正態分佈。c#中的Parallel.for不起作用

using System.Threading.Tasks; 
using System.Threading; 


private void Button_Click(object sender, RoutedEventArgs e) 
     {   ..... 


for (int t = 0; t < normalx.Count; t++) 
      { 
       normaly.Insert(t, (2/((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2))); 
      } 

... 


} 

這是後綴代碼。

要作爲並行線程運行,我把它改爲

Parallel.For(0, normalx.Count, t => 
      { 
       normaly.Insert(t, (2/((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2))); 
      }); 

但建設是好的,但在運行時只有一個線程區域(normalx.Count/8 < - 我的電腦是I7)

是工作和計算。

什麼問題?

+2

什麼是'正常',它是線程安全的? – 2012-04-04 06:38:25

回答

1

TPL並不保證它將爲並行循環使用給定數量的線程。這是可以的,但是它可能會確定開始附加線程的開銷太大,因爲在循環內要完成的工作量並且只在單個線程上運行。

http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel.for.aspx

執行一個for循環中哪些迭代並行運行。

(重點煤礦)

可能能夠迫使多個線程(不是強迫必然是一個好主意)通過提供一個自定義分區,但我還沒有試過,但

http://msdn.microsoft.com/en-us/library/dd560853.aspx

TPL仍然可以自由地說「很好,你提供了一個定製的分區程序,但我仍然要在一個線程上按順序執行每個分區」。我不知道當前實現在這方面的表現如何。

UPDATE

重讀和檢查亨克的評論,我不知道我正確地讀你的問題的第一次。

你是說只有一些法線已經計算出來了嗎?如果是這樣的話,那可能是因爲無論收集什麼後盾normaly都不是線程安全的。

如果是這樣,您可以進行計算,將其分配給臨時變量,然後在實際插入點周圍使用lock。這會造成插入到集合中的瓶頸,但是您仍然可以獲得計算的並行性。

+0

會改變輸入/輸出的區域嗎? – 2012-04-04 06:40:19

+0

@亨克:我可能誤解了這個問題。更新了我的答案。 – 2012-04-04 06:47:42

0

幾乎可以肯定的是normaly.Insert(t, ...)不是線程安全的,也不可能是您想要執行的操作。你想要做的就是提前創建一個空白的數據結構,並提供你需要的所有插槽,然後用你的並行循環來填充它們。你可能會這樣做:

var temp = new double[normalx.Count]; 
Parallel.For(0, normalx.Count, t => 
    temp[t] = 2/((Math.Pow(2 * Math.PI, 0.5)) * rmsnormalvalue)) * 
       Math.Exp(-0.5 * Math.Pow(standardnormalx.ElementAt(t), 2)); 
normaly = temp.ToList();