2012-11-08 74 views
9

我想使用openmp計算2d矩陣的均值。這2d矩陣實際上是一個圖像。使用OpenMP還原

我正在做數據的線程劃分。例如,如果我有N個線程,而不是我使用thread0處理Rows/N個行,依此類推。

我的問題是我可以使用「#pragma omp parallel」的openmp reduction子句嗎? 喜歡的東西

#pragma omp parallel reduction(+ : sum) 
{ 
    if(thread == 0) 
     bla bla code 
     sum = sum + val; 

    else if(thread == 1) 
     bla bla code 
     sum = sum + val; 
} 

回答

14

是的,你可以 - reduction子句是適用於整個並行區域以及個別for工作分享結構。這允許例如還原過在不同的平行部進行計算(重組的代碼的首選方式):

#pragma omp parallel sections private(val) reduction(+:sum) 
{ 
    #pragma omp section 
    { 
     bla bla code 
     sum += val; 
    } 
    #pragma omp section 
    { 
     bla bla code 
     sum += val; 
    } 
} 

還可以使用OpenMP的for工作共享構建自動重新分配的線程之間的循環迭代在隊而不是重新實現它使用部分:

#pragma omp parallel for private(val) reduction(+:sum) 
for (row = 0; row < Rows; row++) 
{ 
    bla bla code 
    sum += val; 
} 

注意,減少變量是私有和它們的中間值(即,值它們在parallel區域的末端還原之前持有)僅部分並不是很有用。例如,下面的串聯迴路不能(容易嗎?)變換爲並行一個帶減速操作:

for (row = 0; row < Rows; row++) 
{ 
    bla bla code 
    sum += val; 
    if (sum > threshold) 
     yada yada code 
} 

這裏yada yada code應在每次迭代一次的sum累計值已經過去的threshold的值來執行。當循環並行運行時,sum的私有值可能永遠不會達到threshold,即使它們的總和值是。

+0

如果他以這種方式分配命令,他就會失去大部分的並行性。 – dreamcrash

+1

@dreamcrash,如果執行正確,有序執行可能不會殺死大部分並行性 - 請參閱[本答案](http://stackoverflow.com/a/13230816/1374437)。 –

+0

的確,我們不能將靜態值用於缺省塊大小。 – dreamcrash

0

在你的情況下,可以sum = sum + val(在2- d陣列或val[rows][cols] = val[rows][cols-1] + val[rows][cols])在1- d陣列解釋爲val[i] = val[i-1] + val[i]其是prefix sum計算。

約簡是前綴求和的方法之一,您可以使用約減到任何可交換關聯運算符,如'+',' - ','*','/'。

+0

'-'和'/'交換關聯怎麼樣? –