※ 引述《Yagyu (近在眼前)》之銘言:
: ※ 引述《DMFC (sole)》之銘言:
: : 貼一部份程式碼,fortran90語法
: do i=1,nx ; do j=1,ny ; do k=1,nz
: csum=sum(coeff(1:np)*cdexp)/Vol
: csumout(i,j,k)=csum
: end do ; end do ; end do
: sum(coeff(1:np)*cdexp)
: 請問這邊是要將整個 coeff(1:23000) 乘上 cdexp 再做 sum 嗎?
: 會這麼問是因為我不確定你未貼上程式碼部分是否還有 np 的 loop
: 如果沒有 np loop, 同時 cdexp 只是個常數,不會隨 nx,ny,nz 變動
: 那可以試著將這部份移出迴圈外, 這樣省得每次 loop 都要重算一遍
: 如果有 np loop, 那請無視我的想法
: 另外輸出的部份
: do i=1,nx
: do j=1,ny
: do k=1,nz
: csumout(i,j,k)=sum(coeff(1:np)*cdexp)/Vol
: end do
: end do
: end do
: do k=1,nz
: do j=1,ny
: do i=1,nx
: csumout(i,j,k)=sum(coeff(1:np)*cdexp)/Vol
: end do
: end do
: end do
: 兩者差異 請參考彭國倫先生的fortran工具書 應該是在陣列章節中的多維陣列那邊
: 沒記錯的話 是跟記憶體存放資料方式有關 這邊變動我想絕對有幫助
謝謝
沒錯~順序影響很大
不過這是因為我手誤
由於我沒法直接貼SOURCE CODE
所以是用手KEYIN
LOOP順序我貼錯了
且~很無奈的
我那個 cdexp 是與 i,j,k 有關
cdexp 非 常數~無法提出
我再貼一次完整的CODE
do iz=0,ngrid(3)-1 ; do iy=0,ngrid(2)-1 ; do ix=0,ngrid(1)-1
xyz(1) = dble(ix)/dble(ngrid(1))
xyz(2) = dble(iy)/dble(ngrid(2))
xyz(3) = dble(iz)/dble(ngrid(3))
atmp = pi2 * (wkiG1*xyz(1) + wkiG2*xyz(2) + wkiG3*xyz(3))
csumout(ix,iy,iz) = sum(coeff(1:nplane)*cdexp(atmp(1:nplane)))/dsqrt(Vol)
end do ; end do ; end do
ngrid(1) ngrid(2) ngrid(3) 都是常數
atmp, wkiG1, wkiG2, wkiG3 都是維度23000(nplane)的大矩陣
Vol, pi2 是常數
cdexp 是 fortran 內有預設的function
意思是對 double precision 的 complex 取 exp
(atmp 是double precision 的 complex)
: : 請問一下
: : 由於資料量不算小
: : 目前測試 nx=ny=nz=47, np=23000
: : 上面貼的部份是需要最久計算的部份
: : 普通執行需要約兩分鐘(測試用參數)
: : 若是把第三行去掉
: : 則可以10秒內結束
: : 可是我就是要把這個資料輸出
: : 才用了一個三維 ARRAY 把資料存起來
: : 然後離開這個 LOOP 後再寫出
: : 如果把 WRITE 寫在 LOOP 內
: : 則情況會更糟
: : 請問有什麼方法可以處理這窘境