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

时间:2015-10-17 12:05:12

标签: c openmp

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

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

第55页的OpenMP 4.0.0 manual偶数状态在循环结构的末尾有一个隐式屏障,除非指定了nowait子句。因此应设置a在这一点上。这里出了什么问题?我错过了什么吗?

#include <stdio.h>
#ifdef _OPENMP
#include <omp.h>
#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;
}

1 个答案:

答案 0 :(得分:3)

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

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

将其初始化到并行区域之外,或者之前使用#pragma omp single将修复代码......