討論區快速選單
知識庫快速選單
網路投保旅行平安險 掌握Salesforce雲端管理秘訣
[ 回上頁 ] [ 討論區發言規則 ]
在不同平台的執行結果會有差異?
更改我的閱讀文章字型大小
作者 : acyang(阿光)
[ 貼文 15 | 人氣 4212 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/1/3 下午 09:44:04
各位前輩大家好,
小弟目前是研究生,
手邊有在跑一些數值分析程式,
我最近發現同一支程式在windows的環境下執行,
會和在linux的環境下執行結果有些差異,
甚至連在windows下,
compaq visual fortran和intel visual fortran編出來的程式執行結果就不同了,
我不了解是什麼原因造成這樣的結果,
能請各位前輩幫我解惑嗎,
謝謝。
作者 : f77f95(f77f95) Fortran頂尖高手貼文超過500則
[ 貼文 548 | 人氣 9 | 評價 3370 | 評價/貼文 6.15 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/1/5 下午 09:42:35

>甚至連在windows下,
>compaq visual fortran和intel visual fortran編出來的程式執行結果就不同了,
>我不了解是什麼原因造成這樣的結果,
>能請各位前輩幫我解惑嗎,
>謝謝。
可以把再倆種編譯器下執行的結果, 還有程式的結構大蓋show一下嗎?
作者 : bsjacky(小文)
[ 貼文 65 | 人氣 567 | 評價 260 | 評價/貼文 4 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人acyang註記此篇回應為很有道理 2007/2/11 上午 11:19:35

>各位前輩大家好,
>小弟目前是研究生,
>手邊有在跑一些數值分析程式,
>我最近發現同一支程式在windows的環境下執行,
>會和在linux的環境下執行結果有些差異,
>甚至連在windows下,
>compaq visual fortran和intel visual fortran編出來的程式執行結果就不同了,
>我不了解是什麼原因造成這樣的結果,
>能請各位前輩幫我解惑嗎,
>謝謝。

編譯器其實是把程式碼轉換為CPU看得懂得碼...
而現代的編譯器往往會作一些最佳化的動作...
而這些都要看編譯器撰寫的功力好壞...
甚至編譯器也有可能編譯出錯誤的碼...
這都是有可能的...
因此compaq visual fortran跟intel visual fortran當然有可能會有不同之執行成果...

舉過去我的經驗為例...
我學長跑的一個程式...
在compaq visual fortran中的debug mode與release mode會有不同答案...
應該說他的release mode會有錯誤訊息出現...
所以他都以debug mode來跑...

我是建議啦...
intel是CPU製造商...
我覺得他對自己產品會比較熟悉...
所以他對自己CPU的最佳化之類的...
製作出來的機械碼...應該會比較好...
而且compaq那個是已經很久的產品了...
所以我建議以compaq為主...

至於不同OS間是否會有影響...
我覺得若真的想知道...
應該要拿intel fortran in Linux與in Windows來比...
不該拿時間差這麼久的產品來比...
有點像是拿PS1跟PS3比...
或是像拿486與Core 2 Duo比...
我是沒比過啦...不過我覺得應該沒差異吧...
作者 : bsjacky(小文)
[ 貼文 65 | 人氣 567 | 評價 260 | 評價/貼文 4 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/2/11 上午 11:19:47

>各位前輩大家好,
>小弟目前是研究生,
>手邊有在跑一些數值分析程式,
>我最近發現同一支程式在windows的環境下執行,
>會和在linux的環境下執行結果有些差異,
>甚至連在windows下,
>compaq visual fortran和intel visual fortran編出來的程式執行結果就不同了,
>我不了解是什麼原因造成這樣的結果,
>能請各位前輩幫我解惑嗎,
>謝謝。

編譯器其實是把程式碼轉換為CPU看得懂得碼...
而現代的編譯器往往會作一些最佳化的動作...
而這些都要看編譯器撰寫的功力好壞...
甚至編譯器也有可能編譯出錯誤的碼...
這都是有可能的...
因此compaq visual fortran跟intel visual fortran當然有可能會有不同之執行成果...

舉過去我的經驗為例...
我學長跑的一個程式...
在compaq visual fortran中的debug mode與release mode會有不同答案...
應該說他的release mode會有錯誤訊息出現...
所以他都以debug mode來跑...

我是建議啦...
intel是CPU製造商...
我覺得他對自己產品會比較熟悉...
所以他對自己CPU的最佳化之類的...
製作出來的機械碼...應該會比較好...
而且compaq那個是已經很久的產品了...
所以我建議以compaq為主...

至於不同OS間是否會有影響...
我覺得若真的想知道...
應該要拿intel fortran in Linux與in Windows來比...
不該拿時間差這麼久的產品來比...
有點像是拿PS1跟PS3比...
或是像拿486與Core 2 Duo比...
我是沒比過啦...不過我覺得應該沒差異吧...
作者 : kominh(owen)
[ 貼文 4 | 人氣 0 | 評價 30 | 評價/貼文 7.5 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人acyang註記此篇回應為最佳解答 2007/4/3 下午 05:47:57
>我最近發現同一支程式在windows的環境下執行,
>會和在linux的環境下執行結果有些差異,
>甚至連在windows下,
>compaq visual fortran和intel visual fortran編出來的程式執行結果就不同了,

應該是Intel compiler最佳化的關係造成浮點運算的精度改變了
如果在linux下可以加上-mp
windows下可以加上/Op
這樣可以控制Intel compiler進行最佳化時避開會造成精度改變的地方
不過程式執行的速度當然也會變慢

另一個原因可能是你有啟動向量化的最佳化選項(-xP, /QxP)
當你啟動這個向量化的選項後當你的迴圈裡面包含三角函數等數學指令
且該行程式被向量化成功, 雖然可以讓執行速度加快, 不過數值的精度影響也更多
因為向量化成功代表會被丟到處理器裡的SSE延伸指令集執行
而不是丟給浮點運算器, 這兩者不同的硬體算出來的結果也就不相同
不過不一定是精度變差, 只是算出來的結果會和debug模式不同

另外windows和linux如果要比較結果盡量使用版本接近的Compiler, 以Intel兩三個月就更新一次的速度, 如果兩邊的compiler版本差異過大可能也會影響執行的數據
作者 : acyang(阿光)
[ 貼文 15 | 人氣 4212 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/8 下午 08:43:26
這支程式可以想成有1000個球
現在用亂數產生程式給它們速度
輸出結果可以從1.DAT看到
在windows環境下COMPAQ FORTRAN(DEBUG或RELEASE)可以正常產生亂數
在LINUX環境下PGI FORTRAN(-O2)INTEL FORTRAN(沒設最佳化)只會輸出同一數字
有趣的是
如果將FUNCTION中WRITE(*,*) IX3,'AFTER'取消註解
則又會正常產生亂數
另外我有發現PGI編譯時如果不加最佳化參數
也是可以正常產生亂數
我在懷疑是不是最佳化的處理影響到函式中在求餘數的地方(MOD)

PROGRAM MAIN
     IMPLICIT REAL*8(A-H,O-Z)
REAL*8 RAN1
COMMON /VEL/ X1(100000),Y1(100000),Z1(100000)
INTEGER, PARAMETER :: NATOM=1000
C assign random initial velocities on [-1,1];
IDUM=-29
DO 100 I=1,NATOM
X1(I)=RAN1(IDUM)
Y1(I)=RAN1(IDUM)
Z1(I)=RAN1(IDUM)
100 CONTINUE
     OPEN(UNIT=46,FILE='1.DAT')
DO 140 I=1,NATOM
WRITE(46,*) X1(I),Y1(I),Z1(I)
140 CONTINUE
CLOSE(46)

STOP
END

REAL*8 FUNCTION RAN1(IDUM)
IMPLICIT NONE
INTEGER IDUM
REAL*8 R(97)
INTEGER, PARAMETER :: M1=259200
INTEGER, PARAMETER :: IA1=7141
INTEGER, PARAMETER :: IC1=54773
REAL*8 RM1
INTEGER, PARAMETER :: M2=134456
INTEGER, PARAMETER :: IA2=8121
INTEGER, PARAMETER :: IC2=28411
REAL*8 RM2
INTEGER, PARAMETER :: M3=243000
INTEGER, PARAMETER :: IA3=4561
INTEGER, PARAMETER :: IC3=51349
INTEGER :: IFF=0
INTEGER IX1,IX2,IX3
INTEGER J

RM1=1.D0/DBLE(M1)
RM2=1.D0/DBLE(M2)

IF((IDUM.LT.0).OR.(IFF.EQ.0))THEN
IFF=1
IX1=MOD(IC1-IDUM,M1)
IX1=MOD(IA1*IX1+IC1,M1)
IX2=MOD(IX1,M2)
IX1=MOD(IA1*IX1+IC1,M1)
IX3=MOD(IX1,M3)
DO J=1,97
IX1=MOD(IA1*IX1+IC1,M1)
IX2=MOD(IA2*IX2+IC2,M2)
R(J)=(DBLE(IX1)+DBLE(IX2)*RM2)*RM1
ENDDO
IDUM=1
ENDIF

IX1=MOD(IA1*IX1+IC1,M1)
IX2=MOD(IA2*IX2+IC2,M2)
IX3=MOD(IA3*IX3+IC3,M3)
C WRITE(*,*) IX3,'AFTER'
J=1+(97*IX3)/M3
IF(J.GT.97.OR.J.LT.1) PAUSE
RAN1=2.D0*R(J)-1.D0
R(J)=(DBLE(IX1)+DBLE(IX2)*RM2)*RM1

RETURN
END
作者 : f77f95(f77f95) Fortran頂尖高手貼文超過500則
[ 貼文 548 | 人氣 9 | 評價 3370 | 評價/貼文 6.15 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/9 下午 08:07:19
問題的關鍵在於 IDUM IFF 這兩個變數在每次呼叫RAN1這個副程式時, 其數值如何變化。 我建議你在
RM1=1.D0/DBLE(M1)
RM2=1.D0/DBLE(M2)
之後加上一條﹕
   WRITE(6,'(A,2I4)') "IDUM IFF = ", IDUM, IFF

你如果可以把這一行的結果 post 上來, 對於問題的判斷會有很大的幫助。


作者 : acyang(阿光)
[ 貼文 15 | 人氣 4212 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/10 下午 04:44:05
第一次呼叫RAN1時
IDUM=-29
IFF=0
之後每次呼叫時
都是IDUM=1
IFF=1
所以那個IF迴圈就不再進去了(我有做過測試了)
以上結果在windows和LINUX上都一樣

不同的就是在LINUX上用PGI編譯時(-O2)
如果有把WRITE(*,*) IX3,'AFTER'這行取消註解
這支程式就可以看到每次IX3都不一樣
所以算出來的的J也都不同
亂數也就可以出來

反之把WRITE(*,*) IX3,'AFTER'這行註解
不知道IX3的變化
但是呢這時候輸出J
就會發現J是同一個數字
結果就永遠輸出同一個亂數

由於這個問題在我編譯時不下(-O2)這個最佳化選項時
就不會發生
所以我才會懷疑是不是最佳化搞的鬼
作者 : f77f95(f77f95) Fortran頂尖高手貼文超過500則
[ 貼文 548 | 人氣 9 | 評價 3370 | 評價/貼文 6.15 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/10 下午 10:04:11
把RAN1當中的 "INTEGER IX1,IX2, IX3" 改成 "INTEGER, SAVE :: IX1, IX2, IX3"
試試看。
作者 : acyang(阿光)
[ 貼文 15 | 人氣 4212 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/11 下午 01:53:39
很遺憾結果還是一樣
只要下了最佳化的參數(-O2)
就只會產生同一個亂數
作者 : f77f95(f77f95) Fortran頂尖高手貼文超過500則
[ 貼文 548 | 人氣 9 | 評價 3370 | 評價/貼文 6.15 | 送出評價 0 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/15 上午 11:29:27
1。 我沒有 PGI Fortran 和 Intel Fortran for Linux, 但是我在 SGI Unix machine 上用MIPS Fortran 77試了一下。 (你的程式必需先調整成 Fortran 77 的語法), 在 "-O0"的情況下, RAN1 每次的結果都不一樣。 在 "-O2" 的情況下, 由第二次起, RAN1 的結果都是同一個數值。

2。 在 RAN1 中加上 "SAVE IX1, IX2, IX3" 這一個指令,在 "-O0" 和 "-O2"的情況下, 每次呼叫 RAN1 都會產生不同的數據。

3。 我認為問題的本源在於不同的編譯器對於 Optimization 有不同的 Implementation.

4。 一個處理這個問題的方法是不用自定的函數去產生亂數。 Fortran 90 以後的版本都有
"Random_Seed" 和 "Random_Number" 這倆個副程式。
作者 : acyang(阿光)
[ 貼文 15 | 人氣 4212 | 評價 0 | 評價/貼文 0 | 送出評價 4 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2007/6/17 下午 09:56:26
多謝你的回應,
我想我會去評估一下FORTRAN內建的亂數產生器了,
因為我是做分子動力學模擬的,
不只一本書或作者都叫我們千萬不要使用程式語言內建的亂數產生器。
現在最壞的打算是在WINDOWS下產生亂數,
儲存成檔案再丟到LINUX上來讀取了。
 板主 : 徵求中
 > Fortran - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - Fortran - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
Fortran
1 f77f95 3300 
2 dennis 470 
3 cc 350 
4 smallpotato 320 
5 qq 290 
6 冼鏡光 230 
7 eraser 220 
8 小文 210 
9 iner 200 
10 wuda 160 
Fortran
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2019 程式設計俱樂部 http://www.programmer-club.com.tw/
0.078125