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 变量的值。那是一种竞争条件。结果可能是错误的,而且速度也会变慢,因为对同一资源的竞争。
通过减少,每个线程都有一个变量的私有副本并使用它。缩减区域完成后,使用缩减运算符将私有副本缩减为最终共享变量。
我已经尝试将此代码片段用于 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 变量的值。那是一种竞争条件。结果可能是错误的,而且速度也会变慢,因为对同一资源的竞争。
通过减少,每个线程都有一个变量的私有副本并使用它。缩减区域完成后,使用缩减运算符将私有副本缩减为最终共享变量。