openmp减少的用途是什么?

时间:2013-05-13 22:32:18

标签: openmp reduction

我有这段并行化的代码。

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,因为它在并行循环之外使用并且在它之外是不可见的。还有减少还包括这个吗?

2 个答案:

答案 0 :(得分:0)

Reducing负责为每个线程制作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> ...

答案 1 :(得分: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添加),那么您可以将atomic替换为critical reduction with OpenMP with SSE/AVX