2016-09-17 5 views
-1

CFD 솔버에서 인덱스 i, j, k 및 l에 따라 각 노드의 도메인 전체에 걸쳐 여러 가지 계산을 적용해야합니다. 도메인은 3-D이며 KMAX + 1에 의해 JMAX + 1에 의해 IMAX + 1의 해상도를가집니다.여러 서브 루틴을 반복적으로 호출하거나 간단히 광범위한 서브 루틴 호출

이 매우 광범위한 블록을 반복적으로 구현하는 것에 관한 문제가 있습니다.

다음 두 가지 방법 중 어느 것이 효율적이며 적은 처리 부하를 생성합니까?

방법 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

당신이 개괄 한 두 가지 옵션의 처리 부하에 대한 생각에 기여하기 위해 지금까지 측정 한 바는 무엇입니까? –

+0

실제로 측정하지 않습니다. 과거에는 두 가지 방법을 모두 구현했으며 방법 1은 시간이 오래 걸리는 것처럼 보였습니다. – Shaqpad

+0

우리가 너에게 해줄 것을 부탁 하나? 당신은 약간의 측정을해야합니다. 코드가 너무 완전하지 않아 성능에서 큰 차이가 나는 분명한 이유가 없습니다. –

답변

1

서브 루틴 sub_1, sub_2, ...이 드라이버 루틴과 동일한 파일에있는 경우 컴파일러 (특정 옵션 없음)는 인라인 할 것인지 선택하지 않을 모든 정보를 가지고 있습니다. 서브 루틴을 직접 인라인하면 컴파일러에서 선택하게됩니다. 가장 좋은 경우 인라이닝을 수행하는 것이 좋은 선택이며 컴파일러가 선택하기 때문에 아무런 차이가 없습니다. 최악의 경우, 컴파일러가 인라인하지 않기 때문에 속도가 느려집니다.

물론 컴파일러가 잘못되었거나 -O0과 같은 옵션이 부적절하기 때문에 잘못 컴파일 된 실행 파일이없는 것으로 가정합니다.

일반적으로 컴파일러에서 최상의 전략을 선택하는 것이 좋으며, 이는 아키텍처와 코드에 따라 다를 수 있습니다. Xeon 또는 Power CPU의 선택 사항이 다를 수 있습니다. 당신이 할 수있는 최선의 방법은 옵션과 지시어 (맨 페이지는 좋은 시작이다)를 통해 컴파일러에 가능한 한 많은 정보를 제공하고 그 일을하게하는 것이다.