2016-09-17 22 views
-1

私のCFDソルバーでは、インデックスi、j、k、lに応じて、各ノードのドメイン全体にいくつかの広範な計算を適用する必要があります。ドメインは3Dで、JMAX + 1の解像度がKMAX + 1である。複数のサブルーチンを繰り返し呼び出すか、単に広範なサブルーチンを呼び出す

私の問題は、これらの非常に広範なブロックを繰り返し実行することです。

次の2つの方法のどちらが効率的で、処理負荷が少なくて済みますか?

方法1

MODULE module_of_method_1 
    IMPLICIT NONE 
    PRIVATE 

    INTEGER, PARAMETER, PUBLIC :: IMIN = 0 , & 
            IMAX = 1024, & 
            JMIN = 0 , & 
            JMAX = 1024, & 
            KMIN = 0 , & 
            KMAX = 1024, & 
            SITE = 32 
    CONTAINS 
    SUBROUTINE sub_1() 
     ! very extentise bLock 1 
    END SUBROUTINE 
    SUBROUTINE sub_2() 
     ! very extentise bLock 2 
    END SUBROUTINE 
    SUBROUTINE sub_3() 
     ! very extentise bLock 3 
    END SUBROUTINE 
END MODULE 

PROGRAM driver_of_method_1 
    USE module_of_method_1 

    IMPLICIT NONE 

    INTEGER :: I, J, K, L 

    DO k = KMIN, KMAX 
     DO j = JMIN, JMAX 
      DO i = IMIN, IMAX 
       DO l = 0, SITE 
        SELECT CASE (case_expression(i, j, k, l)) 
        CASE (case_selector_1) 
         CALL sub_1() 
        CASE (case_selector_2) 
         CALL sub_2() 
         CASE DEFAULT 
         CALL sub_3() 
        END SELECT 
       END DO 
      END DO 
     END DO 
    END DO 
END PROGRAM 

方法2

MODULE module_of_method_2 
    IMPLICIT NONE 
    PRIVATE 

    INTEGER, PARAMETER :: IMIN = 0 , & 
          IMAX = 1024, & 
          JMIN = 0 , & 
          JMAX = 1024, & 
          KMIN = 0 , & 
          KMAX = 1024, & 
          SITE = 32 
    CONTAINS 
    SUBROUTINE only_one_subroutine() 
     INTEGER :: I, J, K, L 

     DO k = KMIN, KMAX 
      DO j = JMIN, JMAX 
       DO i = IMIN, IMAX 
        DO l = 0, SITE 
         SELECT CASE (case_expression(i, j, k, l)) 
         CASE (case_selector_1) 
          ! very extentise bLock 1 
         CASE (case_selector_2) 
          ! very extentise bLock 2 
          CASE DEFAULT 
          ! very extentise bLock 3 
         END SELECT 
        END DO 
       END DO 
      END DO 
     END DO 
    END SUBROUTINE 
END MODULE 

PROGRAM program_of_method_2 
    USE module_of_method_2 

    IMPLICIT NONE 

    CALL only_one_subroutine() 
END PROGRAM 

それはトップダウン簡単なデバッグと設計、開発、および保守の一種であるので、私は、方法1を好みますしかし、私はこの方法の負荷を処理することに懸念があります。

+2

あなたが概説した2つのオプションの処理負荷に関するあなたの考えに貢献するためにこれまでに行った測定はありますか? –

+0

実際に測定は行われません。これまで、私は両方の方法を実装しており、方法1は時間がかかるようでした。 – Shaqpad

+0

私たちはあなたに仕事を依頼していますか?いくつかの測定を行う必要があります。あなたのコードはあまりにも不完全であり、パフォーマンスに大きな違いがあるという明白な理由はありません。 –

答えて

1

サブルーチンsub_1sub_2、...がドライバルーチンと同じファイルにある場合、コンパイラ(特定のオプションはありません)は、インライン化するかどうかを選択するためのすべての情報を持っています。 サブルーチンを自分でインライン化すると、コンパイラに選択肢が与えられます。最良の場合、インライン展開を行うのが良い選択であり、コンパイラもそれを選択するため、違いは見られません。最悪の場合、コンパイラはインライン化を選択しないため、遅くなります。

もちろんコンパイルされていない実行可能ファイルはありません(コンパイラが悪い、または-O0のようなオプションに適合しないためです)。

一般に、コンパイラに最適な戦略を選択させる方が良いです。これは、アーキテクチャとコードによって異なる場合があります。選択肢は、XeonまたはPower CPUで同じではない場合があります。あなたができることは、オプションとディレクティブを使ってコンパイラにできるだけ多くの情報を与えることです(マニュアルページは良いスタートです)。

関連する問題