我已尝试使用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
子句就足以进行此类操作。
我很困惑!
答案 0 :(得分:1)
shared
条款就足以进行此类操作。
不。
删除reduction(+:result)
时,程序导致result
变量上的数据竞争,结果不稳定。
这意味着您可能会得到错误的结果,或偶尔得出正确的结果。
答案 1 :(得分:1)
减少使用您可见的共享变量,但内部变量的私有副本。当您忘记减少子句时,更多线程可能会尝试同时更新减少变量的值。那是一场竞争。结果可能是错误的,并且由于对同一资源的竞争,它也将会变慢。
通过缩减,每个线程都有一个变量的私有副本并使用它。当缩小区域结束时,使用简化运算符将私有副本减少到最终的共享变量。