为什么以下的OpenMP程序无法减少我的变量?

考虑以下最小C代码示例。 当使用export OMP_NUM_THREADS=4 && gcc -fopenmp minimal.c && ./a.out 8上的GCC 4.9.2)进行编译和执行时,这会在我的机器上生成五行rho=100 (有时也是200或400) 。 对于所有五条印刷线,预期输出当然是rho=400

如果我在// MARKER处插入更多代码或在那里放置障碍,该程序更有可能产生正确的结果。 但即使有另一个障碍,它有时会失败,我的计划也会失败。 所以问题似乎是在进入减少循环时a没有正确初始化。

OpenMP 4.0.0手册甚至在第55页上指出, 除非指定了nowait子句,否则在循环结构的末尾有一个隐式屏障。 所以应该在这一点上建立一个。 这里出了什么问题? 我错过了什么吗?

 #include  #ifdef _OPENMP #include  #define ID omp_get_thread_num() #else #define ID 0 #endif double a[100]; int main(int argc, char *argv[]) { int i; double rho; #pragma omp parallel { #pragma omp for for (i = 0; i < 100; i++) { a[i] = 2; } // MARKER rho = 0.0; #pragma omp for reduction(+: rho) for (i = 0; i < 100; i++) { rho += ((a[i])*(a[i])); } fprintf(stderr, "[%d] rho=%f\n", ID, rho); } fprintf(stderr, "[%d] rho=%f\n", ID, rho); return 0; } 

好的我已经得到了答案,但我很生气……

这是一种竞争条件,因为rho是共享的,你可以在并行区域内初始化它,如rho = 0.0;

要么将其初始化到并行区域之外,要么在之前使用#pragma omp single来修复代码……