C OpenMP 代码在 cygwin 上的表现出乎意料,但在 Linux 上的表现与预期一致

C OpenMP code acts unexpectedly on cygwin but just as expected on Linux

int a = 0;
#pragma omp parallel private(a)
{
    a++;
    printf("%d", a);
}

对于 4 核,人们会期望这段代码打印 1111,它在我的 Linux 机器上确实如此。

但是,运行 在我的 Windows 机器上的 cygwin 中,相同的一段代码(相同的标志等)结果为 11117(不确定 1 的数量)。

7 一直都在,一个试过同样的朋友也有 7, 知道这是怎么发生的吗?

我在两台机器上用 "gcc source.c -fopenmp -O2" 编译了代码。

我确实很难重现您的错误,因为正如我在评论中提到的,从 OpenMP 标准的角度来看,您的代码具有未定义的行为。实际上,在进入 parallel 区域时声明为 private 的变量不会进行任何初始化,除非它们被声明为 firstprivate.

在你的例子中,你增加了一个变量,它的值可以是任何值,然后打印它。所以打印的值也可以是任何值,包括您期望看到的值。

事实证明,对我来说,为了重现 1 和 7 的系列,我不得不编译代码,禁用编译器的任何优化。 一旦用 firstprivate 修复了代码,所有结果都是 1s。

修复前:

$ gcc -O0 -fopenmp foo.c
$ OMP_NUM_THREADS=5 ./a.exe
71111
$ OMP_NUM_THREADS=5 ./a.exe
17111

代码修复:

#include <stdio.h>
int main () {
    int a = 0;
    #pragma omp parallel firstprivate(a)
    {
        a++;
        printf("%d", a);
    }
    return 0;
}

然后

$ gcc -O0 -fopenmp foo.c
$ OMP_NUM_THREADS=5 ./a.exe
11111