2013-10-27 1 views
0

기본적인 질문이 있습니다. 아래 코드에서 동일한 함수 인 'add'를 두 번 호출합니다. OpenMP를 사용하여이 작업을 수행 할 때 잘못된 결과가 나타납니다. 'N'OpenMP 포트란 스레드의 함수 호출

: I의 주석을 라인 (22), 즉 저된다 이용하는 스레드 '! ( ,)을 작성'하면 그러나

sum for 10= 45.0000000    0   10 

sum for 5= 45.0000000    1   5 

:

program p 
integer::i,j,omp_get_thread_num,n 
real::suma 
i=5 
j=10 

!$omp parallel num_threads(2) private(n) 

n=omp_get_thread_num() 

if(n==0) goto 1111 

suma=add(i,n) 

write(*,*)'sum for 5=',suma,n,i 

goto 1000 

1111 suma=add(j,n) 

write(*,*)'sum for 10=',suma,n,j 

1000 continue 

!$omp end parallel 

end program p 
!---------------------------------------- 

function add(k,n)result(l) 

implicit none 

integer::k,s,n 

real::l1,l 

!write(*,*)'thread employing me is:',n 

l1=0.0 

do s=k,k+5 

l1=l1+s 

end do 

l=l1 

return 

end function add 

이 코드를 실행 한 결과이다

결과는 다음과 내가 같은를 사용하기 위해 무엇을해야

thread employing me is:   0 

sum for 10= 75.0000000    0   10 

thread employing me is:   1 

sum for 5= 45.0000000    1   5 

함수 (즉, 변수를 섞지 않고) 다른 스레드를 사용하는 함수 아무도 결과를 얻을 수 설명 할 수 있습니까?

이것은 실제 문제의 단순한 버전입니다. (스레드에서 같은 함수를 사용하고있는 곳)

편집 : 좋아, 나는 개인 목록에 'suma'를 포함시키지 않는 매우 어리석은 실수를 깨달았다. 그러나 누군가 22 행이 주석 처리되지 않은 경우 왜 수마가 비공개로 설정되지 않아도 항상 올바른 결과를 제공하는 이유를 말할 수 있습니까?

+0

내 생각은'write' 문은 어떻게 든 "어떤 종류의 것으로 될 것이다 암시 적 장벽 ", st 서로 다른 스레드의 서로 다른 쓰기 문은 줄 바꿈 대신 줄무늬로 표시됩니다. –

+0

'private' 절의리스트에'suma'를 추가해야합니다. 그리고 실제로 OpenMP 섹션을 사용해야합니다. –

답변

4

프로그램에 데이터 경쟁 조건이 있습니다. suma은 (OpenMP의 암시 적 데이터 공유 규칙에 따라) shared이며 두 스레드가 동시에 할당합니다. write 문을 주석 해제하면 두 번째 스레드가 실행될 때 약간의 오프셋이 생겨 경쟁 조건이 숨겨집니다 (내 OS X에서는 해당 프로그램이 무작위로 두 번 45.0 또는 두 번 75.0으로 인쇄됩니다).

!$omp parallel num_threads(2) private(n, suma) 
... 
!$omp end parallel 

게다가, 당신은 정말 정말 정말 대신이 고용 한 goto 논리의 OpenMP의 섹션을 사용해야합니다

!$omp parallel num_threads(2) private(n, suma) 
n=omp_get_thread_num() 

!$omp sections 
suma=add(i,n) 
write(*,*)'sum for 5=',suma,n,i 
!$omp section 
suma=add(j,n) 
write(*,*)'sum for 10=',suma,n,j 
!$omp end sections 

!$omp end parallel 
관련 문제