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
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