Reduction(op:var) 与 shared(var) 效果相同

Reduction(op:var) has the same effect as shared(var)

我已经尝试将此代码片段用于 reduction(op:var) 概念验证,它工作正常并给出结果 = 656700

int i, n, chunk;
float a[100], b[100], result;
/* Some initializations */
n = 100; chunk = 10; result = 0.0;
for (i=0; i < n; i++) {
    a[i] = i * 1.0;
    b[i] = i * 2.0;
}
//Fork has only for loop
#pragma omp parallel for default(shared) private(i) schedule(static,chunk) reduction(+:result)
for (i=0; i < n; i++)
    result = result + (a[i] * b[i]);
printf("Final result= %f\n",result);

当我尝试相同的代码但没有 reduction(+:result) 时,它给了我相同的结果 656700! 我认为这非常有意义,因为缩减依赖于共享变量,换句话说,shared 子句足以进行此类操作。

我很困惑!

shared clause would be sufficient for such operation.

没有。

当您删除 reduction(+:result) 时,程序会导致 result 变量上的数据争用并且结果不稳定。 这意味着您可能会得到错误的结果,或偶尔得到正确的结果。

Reduction 使用您可见的共享变量,但在内部使用该变量的私有副本。当您忘记 reduction 子句时,更多线程可能会尝试同时更新 reduction 变量的值。那是一种竞争条件。结果可能是错误的,而且速度也会变慢,因为对同一资源的竞争。

通过减少,每个线程都有一个变量的私有副本并使用它。缩减区域完成后,使用缩减运算符将私有副本缩减为最终共享变量。