windows - 跨线程的数值差异(cygwin 上的 openMP)

标签 windows multithreading cygwin fortran 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 总是显示相同的结果,与所有其他线程不同。我还观察到,当更改要生成的线程数时(export 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 double 通常只有 15 guaranteed significant digits

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

通常这意味着,由于浮点运算的复杂性,第 15 位数字之后的所有内容都不可信任。

您可能想阅读那个 here

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

... this guarantee is mostly straightforward (if you haven’t recompiled then you’ll get the same results) but nailing it down precisely is tricky.

...

So the guarantee is really that the same machine code will produce the same results, as long as you don’t do something wacky.

...

另外 this 系列文章,关于 double ,您可能​​也会感兴趣。

关于windows - 跨线程的数值差异(cygwin 上的 openMP),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24823011/

相关文章:

c++ - 如何在运行时将信息传递给线程?

Git 在 Mac 和 Windows 同时使用时会产生不必要的冲突

c++ - 在 C++ 中使用原子 TestAndSet 混合无锁和全锁线程同步

c - setjmp longjmp 在 Netbeans cygwin Windows XP 下崩溃

java - 在 Windows-7 64 位上运行 hadoop

c++ - 将传统 Windows 桌面应用程序提交到 Windows 应用商店

c# - 位于 linux 服务器上的 PHP 代码需要运行 windows .exe

c# - 如何实现与 WNetAddConnection2 相同的超时?

当 AWT 调度线程已执行可运行时 Java 发出通知

javascript - 为什么Java可以无限循环?对此有何建议