2012-11-09 75 views
1

我最近嘗試在Visual Studio中試用OpenMP,以瞭解如何對我的程序進行多線程。OpenMP with Visual Studio:競爭條件

如果我嘗試連續執行此代碼:

int totalSum = 0; 

for(int x=0; x < 100; x++) 
{ 
    for(int y=0; y < 100; y++) 
    { 
     totalSum = totalSum + x + y; 
    } 
} 

我最終得到的是該totalSum = 990000

當我嘗試只是說添加OpenMP的功能:

#pragma omp parallel for 
    for(int x=0; x < 100; x++) 
    { 

     for(int y=0; y < 100; y++) 
     { 
      totalSum = totalSum + x + y; 
     } 
    } 

我以totalSum = 491293或596865或638260等結束......

很明顯,發生的事情是競爭情況似乎正在發生,並且取決於哪個線程首先訪問totalSum,最終答案不同。

我在做什麼不正確? x和y被正確定義爲私有變量(因爲它們是在並行區域內創建的)。

我可以做些什麼來確保當我對多線程程序進行多線程處理時,與我在串行執行時相比,我可以得到相同的答案?

+0

您的比賽條件是'totalSum'... – Mysticial

回答

2

解決方法是使用reduction條款:

int totalSum = 0; 

#pragma omp parallel for reduction(+:totalSum) // reduction 
for(int x=0; x < 100; x++) 
{ 

    for(int y=0; y < 100; y++) 
    { 
     totalSum = totalSum + x + y; 
    } 
} 

閱讀上OpenMP的減少,然後你就會明白它是如何工作的。

+0

謝謝Mysticial。我曾閱讀過關於減少的內容,似乎它與關鍵區域具有類似的功能。 – c0d3rz

+0

有點兒。它比關鍵區域更智能。它真正的作用是給每個線程一個總和的本地副本。這些都是單獨添加的。然後當所有的線程完成時,局部總和被加起來以在最後完成最後的總和。這避免了對關鍵區域的需求。 – Mysticial

+0

嘿神祕:我正在玩一些代碼,我注意到如果我改變了totalSum = x + y;並且將reduce語句保留在那裏,我遇到了OpenMP輸出與串行執行不匹配的另一種競爭條件。我只是無法弄清楚爲什麼會發生這種情況......請指點一下嗎? – c0d3rz