2013-05-13 65 views
2

我有這段並行化的代碼。減少openmp的用法是什麼?

int i,n; double area,pi,x; 
area=0.0; 
#pragma omp parallel for private(x) reduction (+:area) 
for(i=0; i<n; i++){ 
x= (i+0.5)/n; 
area+= 4.0/(1.0+x*x); 
} 
pi = area/n; 

據說減少將消除如果我們不使用減少可能發生的競爭條件。仍然我想知道我們是否需要爲區域添加lastprivate,因爲它在並行循環外部使用,並且不會在其外部可見。其他的減少是否也包括在內?

+0

你不想使用最後一個私有。閱讀此鏈接以瞭解OpenMP中的減少,firstprivate,lastprivate和其他內容。 http://bisqwit.iki.fi/story/howto/openmp/#ReductionClause。查看我的答案,瞭解更多關於減少的信息。 – 2013-05-14 21:07:15

回答

0

減少處理爲每個線程製作area的私人副本。一旦平行區域結束區域在一次原子操作中減少。換句話說,公開的area是每個線程的所有私有area的集合。

thread 1 - private area = compute(x) 
thread 2 - private area = compute(y) 
thread 3 - private area = compute(z) 

reduction step - public area = area<thread1> + area<thread2> + area<thread3> ... 
+0

謝謝。所以pi得到正確的值而不是0?除非定義爲lastprivate,否則我認爲在並行部分之外定義的值會丟失循環外部的值。 – MadHatter 2013-05-13 23:17:10

0

你不需要lastprivate。爲了幫助您瞭解如何進行減排,我認爲通過atomic瞭解如何實現這一點很有用。下面的代碼

float sum = 0.0f; 
pragma omp parallel for reduction (+:sum) 
for(int i=0; i<N; i++) { 
    sum += // 
} 

相當於

float sum = 0.0f; 
#pragma omp parallel 
{ 
    float sum_private = 0.0f; 
    #pragma omp for nowait 
    for(int i=0; i<N; i++) { 
     sum_private += // 
    } 
    #pragma omp atomic 
    sum += sum_private; 
} 

雖然這種替代有更多的代碼是有幫助的展示瞭如何使用更復雜的運營商。起訴reduction的一個限制是atomic只支持一些基本的操作符。如果你想使用更復雜的操作符(如SSE/AVX添加),那麼你可以用critical代替atomicreduction with OpenMP with SSE/AVX