いわて駐在研究日誌2。

NEVER STAND BEHIND ME

pgfortran/CUDA Fortran演習2

(昨日の続き)

pgmon.outが作成されたので、pgprofで確認してみた。(pgprof -exe a.out)

計算時間がかかっているものから並べると

main 92%

is_raycross 2%

geometres 2%

rot_vec 1%

check_face 1%

   :

ということで、予想通りmainルーチンの中の計算時間が圧倒的。

さらに、mainの中を見ると、

290    if(k /= i .and. k /= j                     .and. &         (2629.1s)

295    wkvec1(1:3) = cgb(k,1:3) - cgb(i,1:3)          (2318.6s)

の2行でほぼ70%強を費やしていることが分かった。

 

①295行目の対策(3重ループの最内側にあるこちらを先に)

毎回 cgb(i,1:3)にアクセスするのは無駄と思われるので、

kループの外で一度ワーク配列にコピーし、それを使うように変更してみた。

→ 295    wkvec1(1:3) = cgb(k,1:3) - wkvec0(1:3)                     (2102.7s)

  1割ぐらいしか変化なし。

②290行目の対策

→     290   こんな感じにすると
          if(k == i .or. k == j) exit
          if(cgb(k,1) >= xmin .and. cgb(k,1) <= xmax .and. &
             cgb(k,2) >= ymin .and. cgb(k,2) <= ymax .and. &
             cgb(k,3) >= zmin .and. cgb(k,3) <= zmax       )then                  (2464.9s)

        おお、結構減った。さらにこのようにしてみる(fast out)。

         if(k == i) exit
         if(k == j) exit
          if(cgb(k,1) < xmin) exit
          if(cgb(k,1) > xmax) exit
          if(cgb(k,2) < ymin) exit
          if(cgb(k,2) > ymax) exit
          if(cgb(k,3) < zmin) exit
          if(cgb(k,3) > zmax) exit                                                     (21.64 s)

   すごく減りました。計算結果も問題ない感じです。

  複雑なif文は書いては行けないということですね。