0

我有一个基本问题。在下面的代码中,我调用了相同的函数“add”两次。当我使用 OpenMP 执行此操作时,我得到的结果不正确。

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

执行这段代码的结果是:

sum for 10=   45.0000000               0          10

sum for 5=   45.0000000               1           5

但是,当我取消注释第 22 行时,即 '!write( , )' 使用我的线程是:',n'

结果是:

 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 行没有注释,它总是给出正确的结果,即使 suma 没有被私有化?

4

1 回答 1

4

您的程序中存在数据竞争条件。sumashared(通过 OpenMP 的隐式数据共享规则)并且两个线程同时分配给它。取消注释该write语句会导致第二个线程的执行略有偏移,因此隐藏了竞争条件(它不在我的 OS X 上 - 它只是让程序随机打印两次45.0或两次75.0)。

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

除此之外,您真的应该真正真正地使用 OpenMP 部分而不是goto您使用的逻辑:

!$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
于 2013-10-27T21:52:24.967 回答