考虑以下最小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=%fn", ID, rho); } fprintf(stderr, "[%d] rho=%fn", ID, rho); return 0; }
好的我已经得到了答案,但我很生气……
这是一种竞争条件,因为rho
是共享的,你可以在并行区域内初始化它,如rho = 0.0;
要么将其初始化到并行区域之外,要么在之前使用#pragma omp single
来修复代码……
以上就是c/c++开发分享为什么以下的OpenMP程序无法减少我的变量?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/544968.html