2

我有这段并行化的代码。

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,因为它在并行循环之外使用并且在它之外不可见。否则减少是否也涵盖了这一点?

4

2 回答 2

2

Reduction 负责area为每个线程制作一个私有副本。一旦平行区域结束,面积就会在一个原子操作中减少。换句话说area,暴露的是area每个线程的所有 private 的聚合。

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> ...
于 2013-05-13T22:38:47.737 回答
1

你不需要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;
}

尽管此替代方案有更多代码,但它有助于展示如何使用更复杂的运算符。起诉时的一个限制reductionatomic仅支持少数基本运算符。如果您想使用更复杂的运算符(例如 SSE/AVX 加法),则可以将OpenMP 替换为 SSE/atomic AVXcritical

于 2013-05-14T13:32:19.380 回答