2016-09-19 2 views
1

이 질문은 Fortran 관점에서 작성했지만 질문은 Fortran만으로 제한되지 않습니다 (따라서 C++ 태그).openmp 병렬 대기 시간을 완화하기위한 조치

두 가지 질문이 있습니다. OpenMP 병렬 루프 here의 시작과 중지에 대기 시간이 있다는 것을 읽었습니다. 내 질문은 다음과 같습니다.

Q1) OpenMP 대기 시간을 줄이기위한 실질적인 방안은 무엇입니까?

질문 2 다음 중 성능이 더 좋은 방법은 무엇입니까?

방법 1

x = 1.0; y = 2.0 
!$OMP PARALLEL DO 
do k=1,Nz; do j=1,Ny; do i=1,Nx 
x(i,j,k) = x(i,j,k)+y(i,j,k) 
enddo; enddo; enddo 
!$OMP END PARALLEL DO 

!$OMP PARALLEL DO 
do k=1,Nz; do j=1,Ny; do i=1,Nx 
x(i,j,k) = x(i,j,k)*y(i,j,k) 
enddo; enddo; enddo 
!$OMP END PARALLEL DO 
! (x should = 6.0 at this point) 

방법 2

x = 1.0; y = 2.0 
!$OMP PARALLEL DO 
do k=1,Nz; do j=1,Ny; do i=1,Nx 
x(i,j,k) = x(i,j,k)+y(i,j,k) 
x(i,j,k) = x(i,j,k)*y(i,j,k) 
enddo; enddo; enddo 
!$OMP END PARALLEL DO 
! (x should = 6.0 at this point) 

방법 3

1) 절차

의 배열을 포함하는 객체를 만들기

x = 1.0; y = 2.0 
!$OMP PARALLEL DO 
do k=1,Nz; do j=1,Ny; do i=1,Nx 
do t=1,procedure_array%N 
call procedure_array%single_procedure(t)%P(x(i,j,k),y(i,j,k)) 
enddo 
enddo; enddo; enddo 
!$OMP END PARALLEL DO 
! (x should = 6.0 at this point) 

을 다음과 같이

2)의이 procedure_array%N = 2

procedure_array%single_procedure(1) 
procedure_array%single_procedure(2) 

포인트 add (x=x+y)와 multiply (x=x*y)이 각각 서브 루틴 것을 가정하자 절차의 배열을 호출합니다.

3) 정리 (할당 해제)

댓글

첫째, 그것은 방법이이 방법 1보다 우수 분명하다, 그래서 나는 방법 3 방법 2의 비교에 정말 관심이 있어요. 둘째, "시도하고보고"하는 것이 유효한 답변이지만, 방법 3이 방법 2와 비교하여 열등한 이유 (또는 산업) 또는 개념적 이유에서 사용되는 방법 3의 구체적인 예가 있는지 알고 싶습니다. (예 : 많은 프로 시저 호출로 인한 오버 헤드). 마지막으로, 메소드 2와 3을 실질적으로 동등하게 만들기 위해 (예 : 특정 스레드를 구체적으로 지정하여) 수행 할 수있는 특별한주의가 있다면, 그것들은 무엇입니까?

감사합니다.

업데이트 의견에 비추어

, 나는 다음과 같은 수정했습니다.

  • 는 작업을 수정 (감사 @Gilles)
  • MPI와 관련된 제거 모든이 정말 OpenMP를 질문 (@Vladimir 감사합니다) 아래
  • 추가 된 설명 (내 자신의 실현)
  • 입니다

감사합니다. @innoSPG, 캐시 메모리 (및 캐시 오류)에 대한 귀하의 답변에 대해 매우 유익하고 도움이되었습니다.

대한 설명은 마지막으로

, 코멘트에서, 나는이 질문의 초점은 프로 시저 호출에 대해 실제로 엄격 OpenMP의 병렬화와 관련이없는 것을 깨달았다. 즉, openmp 진술을 남겨 두었습니다. 왜냐하면 이것이 가능한 한 더 복잡한 응용 프로그램에서 진행되고 있기 때문입니다. 가능한 한 많이 보존하고 싶습니다. @ Chaosit의 코멘트에서 프로 시저 호출에 오버 헤드가 필요하고 메서드를 느리게하는 것처럼 보입니다. 3.이 문제를 해결할 방법이 있습니까?

또한 잘못 입력했으면 수정 해주세요. 그러나 방법 2의 두 가지 작업이 올바른 최종 x 값이 된 순서대로 실행됩니다.

+1

스 니펫의 두 계산이 모두 의미가 없다는 점을 제외하고는 (확인 만하면 계산이 가능함) ** 방법 1 **과 ** 방법 2 **는 동일하지 않습니다. 주문 문제 (이 경우 많은). 따라서 "방법 2는 방법 1보다 우수합니다"라는 주장은 ** 방법 1 **에서 얻은 결과 인 경우 ** 방법 2 **가 잘못 되었기 때문에 매우 의문 스럽습니다 (단, a = b = 0이 아닌 경우).나는 이것이 당신의 요점이 아니라는 것을 알고 있습니다. – Gilles

+1

* "MPI 병렬화 루프"*가 정확히 무엇을 의미합니까? 그런 일은 없습니다. –

답변

4

제 생각에 여러분이 찾고있는 차이점은 (방법 2와 방법 3) 병렬 처리에 의존하지 않는다는 것입니다.

설명해 드리죠 :

방법 (3) 아마도 내가 프로 시저 포인터에 익숙하지이기 때문에 나는 그러나, 아마도 말하고 방법 2에 존재하지 않는 때문에 프로 시저 호출에 또 다른 부담을해야합니다, 내 생각 엔이 있다는 것입니다 프로 시저 포인터를 사용하는 경우 컴파일러에 의한 최적화는 프로 시저 호출을 인라인하지 않습니다.

프로 시저 호출로 인한 오버 헤드는 절대적으로 병렬화와 무관합니다. 당신은 여전히 ​​순차적 인 코드로 그것을 가질 것입니다. 이것은 병렬화 대기 시간의 일부가 아닙니다.

이제는 마음에 들지 않는 옵션으로 돌아가는 위험을 감수하고 있습니다. 시도해보십시오. 나는 당신이 보여준 것이 단지 당신의 문제에 대한 예시 일 뿐이며 실제 사례가 더 복잡하다고 믿기 때문에이 위험을 감수하고 있습니다. 복잡한 사례가 발생하면 방법 1과 2 사이의 결론이 더 이상 유효하지 않다는 사실에 놀랄 수 있습니다. 손에 쥐고있는 문제에 크게 의존 할 수 있습니다. 한 가지 경우에 대한 결론은 다른 것에 대한 결론을 지키지 않습니다. 현재 컴파일러만큼 지능적이므로 모든 것을 포착하지는 않습니다. 컴퓨터 과학에서 캐시 메모리에 대한 개념은 잘 이해되지 않는 경우가 있지만 자세한 내용은 다루지 않을 것입니다. 사례 2의 결합 루프가 캐시 메모리에 보관되지 않는 동안 방법 1의 각 단일 루프 (데이터 및/또는 코드)가 캐시 메모리에 보관되는 경우를 가질 수 있습니다. 단순한 설명은 방법 2가 내부 루프 내부에서 캐시 결함을 경험하는 반면 방법 1은 내부 루프에서 캐시 결함을 경험하는 경우이다. 이 경우 메소드 1은 큰 루프 경계에 대해 메소드 2보다 월등히 우수하다는 것을 알 수 있습니다.

여기가 Try and see이 표준이되는 곳이며 실제 생활에서 대부분의 경우 발생합니다.

+1

세 번째 방법과 관련해서는 맞습니다. 프로 시저 포인터가 컴파일 타임이 아닌 런타임에서 처리된다는 사실 때문에 처음 두 메서드와 비교할 때 속도가 느려질 가능성이 큽니다. 따라서 컴파일러는 코드의이 부분을 최적화하기 위해 아무 것도 할 수 없습니다 - 그대로 사용해야합니다. 처음 두 가지 방법의 비교에 관해서 - 이것은 컴파일러에 크게 의존 할 것이지만 - 현대 컴파일러를 사용하면 둘 다 똑같이 빠르게 수행 할 수 있다고 기대할 것입니다 – Chaosit

관련 문제