2014-07-18 19 views
5

我期望以下fortran代碼爲所有線程生成相同的結果。我正在使用最新的cygwin工作在32位Windows 7上。 Gfortran版本是4.8.3線程之間的數值差異(cygwin上的openMP)

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 

在我的機器,我得到

[email protected]_radg ~/morralla/terror 
$ gfortran terror.f90 -fopenmp 

[email protected]_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

同樣錯誤的結果當改變優化級別,我取得好成績然而

[email protected]_radg ~/morralla/terror 
$ gfortran -O3 terror.f90 -fopenmp 

[email protected]_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 

任何想法爲什麼會發生在我的特定環境?

+0

我有一個類似的設置,我可以重現該問題。任何優化都會使所有openMP線程給出相同的結果,但沒有優化只會爲線程0產生不同的值。 – siritinga

+4

爲什麼使用'dsqrt'?自1977年以來,通用'sqrt()'和我們在一起。而且,Fortran 2008引入了'hypot'和'norm2',但它們並不便攜。 –

+0

與通用的sqrt()我仍然得到相同的結果 – Calculon

回答

1

你有沒有想過,Fortran雙精度通常只有15 guaranteed significant digits

Thread   1 results: 8.7800911157003387  676.85722410933931 
Thread   0 results: 8.7800911157003370  676.85722410933886 
Digits      : 1 23456789--  123 456789-- 

一般來說,這意味着,在15位之後,一切都不能使用,因爲浮點運算的複雜的信賴。

您可能想了解一下here

特別this後的系列,涉及精密,解釋,爲什麼你總是在線程0相同的結果,只要你不重新編譯:

... 這個保證主要是簡單(如果你沒有重新編譯,那麼你會得到相同的結果),但確切地說,它是非常棘手的。

...

所以,保證是真的,同樣的機器代碼會產生相同的結果,只要你不做些什麼古怪。

...

此外this後的系列,關於雙打您可能感興趣了。