2016-08-28 7 views
1

내 문제는 관련되거나 심지어 동일한 문제로 묘사 된 것 같아 here. 그러나 실제로 일어나는 일을 이해하지 못합니다.병렬 환경에서 서브 루틴 호출

I는 gfortran 컴파일러 OpenMP를 사용하고 난 할 다음 태스크있다 : I는 XY y는 좌표 x 좌표와 이차원 표면 밀도 분포 F(X, Y)있다. 행렬 F은 크기가 Nx x Ny입니다.

이제 좌표가 Xp(i)Yp(i)이므로이 점에 밀도를 보간해야합니다 (F). 이 문제는 병렬 처리를 위해 만들어졌습니다.

i을 제외한 모든 항목이 공유됩니다. interp2d 함수는 몇 가지 간단한 선형 보간 작업을 수행하고 있습니다.

하나의 스레드에서는 문제가 없지만 멀티 스레드에서는 실패합니다. Numerical Recipes에서 가져온 hunt -subroutine으로이 문제를 추적 한 결과, interp2d이 호출되었습니다. hunt - 서브 루틴은 기본적으로 과 같은 인덱스 ix을 계산합니다. 이것은 보간의 시작점을 얻는 데 필요합니다. 그것을 멀티 스레딩으로

하나 개의 스레드가 hunt에서 올바른 인덱스 ixXp(i) 그 시점에 근처에도없는 경우에도 다음 hunt를 호출 동일한 인덱스를 가져옵니다 스레드를 얻는 것을, 이제 다음마다 발생합니다.

!$OMP PARALLEL DO DEFAULT(SHARED) PRIVATE(i) 
    do i=1, Nmax 

     ! Some stuff to be done here 

    !$OMP CRITICAL 
     Fint(i) = interp2d(Xp(i), Yp(i), X, Y, F, Nx, Ny) 
    !$OMP END CRITICAL 

     ! Some other stuff to be done here 

    end do 
!$OMP END PARALLEL DO 

을하지만 이것은 효율성을 감소 :

나는 CRITICAL 환경을 사용하여 이러한 문제를 방지 할 수 있습니다. 예를 들어 세 개의 스레드를 사용하면 CRITICAL 환경에서 평균 1.5의로드가 발생합니다. 내가 평균 2.75의로드 평균을 가지고 있지 않더라도 잘못된 결과와 경우에 따라 SIGSEGV 런타임 오류가 발생합니다.

정확히 여기서 무엇이 일어나고 있습니까? 모든 스레드가 동일한 hunt -subroutine을 호출하고 있으며 동시에 처리하는 경우 충돌이있는 것으로 보입니다. 말이 돼?

어떻게 방지 할 수 있습니까?

+1

'hunt' 서브 루틴이 스레드로부터 안전하지 않은 것처럼 보입니다. 'critical2' 지시자를'interp2d' 호출에서'interp2d' 호출로 옮깁니다. (가능한 한 낮은 수준으로). – Gilles

+1

'interp2d'와'hunt' 루틴의 코드를 게시 할 수 있습니까? 일반적으로 코드를 작성하는 데 '중요'해야하는 것은 동시에 여러 스레드가 읽고 쓰는 공유 리소스 (예 : 변수)가 있기 때문입니다. – smateo

+0

Numerical Recipes에서 서브 루틴을 게시 할 수 있는지 확실하지 않습니다. 그러나 나는 나중에 단순화 된 것을 게시 할 것이다. 지금까지 모든 스레드가 동일한 스택에 액세스하고 때로는 루틴의 실행 시간에 따라 스택에서 올바른 순서로 더미 변수를 읽지 않는다고 생각합니다. 그게 말이 되니? 모든 스레드가 자신의 전용 스택을 갖도록 강제 할 수 있습니까? – Sebastian

답변

1

Fortran 90+에서 변수 선언과 초기화를 결합하면 변수에 SAVE 속성을 부여하는 부작용이 있습니다.

integer, save :: i 

if (first_invocation) then 
    i = 0 
end if 

SAVE 변수 루틴 여러 호출 사이 그들의 값을 유지하고, 따라서 종종 정적 변수로 구현 거라고 :

integer :: i = 0 

은 거의 비슷하다. OpenMP에서 암시 적 데이터 공유 클래스를 관리하는 규칙에 따라 이러한 변수는 threadprivate 지시문에 나열되어 있지 않으면 공유됩니다.

OpenMP는 기본 언어가 Fortran 77 인 경우에도 호환 컴파일러가 위의 의미를 적용하도록 요구합니다.