线程之间的数值差异(cygwin上的openMP)

我期望以下fortran代码为所有线程生成相同的结果。 我正在使用最新的cygwin工作在32位Windows 7上。 Gfortran版本是4.8.3

program strange use omp_lib implicit none real(kind=8) :: X(3) real(kind=8) :: R real(kind=8) :: R3 !$omp parallel private(X,R,R3) default(none) X(1)=7.d0 X(2)=5.3d0 X(3)=0.d0 R = dsqrt(X(1)**2 + X(2)**2 +X(3)**2) R3 = R*R*R write(*,*) "Thread ", omp_get_thread_num(), " results: ", R, R3 !$omp end parallel end program 

在我的机器上,我得到了

 radg@pc_radg ~/morralla/terror $ gfortran terror.f90 -fopenmp radg@pc_radg ~/morralla/terror $ ./a.exe Thread 1 results: 8.7800911157003387 676.85722410933931 Thread 0 results: 8.7800911157003370 676.85722410933886 Thread 2 results: 8.7800911157003387 676.85722410933931 Thread 3 results: 8.7800911157003387 676.85722410933931 

运行几次之后,我发现线程0总是显示相同的结果,与所有其他线程不同。 我还观察到,当更改要生成的线程数(导出OMP_NUM_THREADS = x)时,我仍然从线程0得到相同的错误结果

当改变优化级别时,我得到了很好的结果

 radg@pc_radg ~/morralla/terror $ gfortran -O3 terror.f90 -fopenmp radg@pc_radg ~/morralla/terror $ ./a.exe Thread 0 results: 8.7800911157003387 676.85722410933931 Thread 1 results: 8.7800911157003387 676.85722410933931 Thread 3 results: 8.7800911157003387 676.85722410933931 Thread 2 results: 8.7800911157003387 676.85722410933931 

相同的程序在linux 64位机器(32位和64位二进制文​​件)上正常工作。 这种输出的例子

  Thread 3 results: 8.7800911157003387 676.85722410933931 Thread 0 results: 8.7800911157003387 676.85722410933931 Thread 1 results: 8.7800911157003387 676.85722410933931 Thread 2 results: 8.7800911157003387 676.85722410933931 

任何想法为什么会发生在我的特定环境?

您是否考虑过,Fortran双精度通常只有15个有效位数 ?

 Thread 1 results: 8.7800911157003387 676.85722410933931 Thread 0 results: 8.7800911157003370 676.85722410933886 Digits : 1 23456789012345-- 123 456789012345-- 

一般而言,这意味着,由于浮点运算的复杂性,第15位以后的所有内容都是不可信的。

你可能想在这里阅读。

特别是关于精度的这个帖子,解释了为什么你总是在线程0上得到相同的结果,只要你不重新编译:

…这个保证大多是直截了当的(如果你没有重新编译,那么你会得到相同的结果),但确切地说,它是棘手的。

所以保证是真的,相同的机器代码会产生相同的结果,只要你不做一些古怪的事情。

另外这个系列的帖子,关于双打也可能让你感兴趣。