Function 在OpenMP fortran线程中调用函数

Function 在OpenMP fortran线程中调用函数,function,parallel-processing,fortran,openmp,Function,Parallel Processing,Fortran,Openmp,我有一个基本问题。在下面的代码中,我两次调用同一个函数“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

我有一个基本问题。在下面的代码中,我两次调用同一个函数“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行时,即“!写(,)‘雇用我的线程是:’,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不是私有的吗?

程序中存在数据争用情况
suma
共享的
(通过OpenMP的隐式数据共享规则),并且两个线程同时分配给它。取消对
write
语句的注释会导致第二个线程的执行出现轻微偏移,因此会隐藏争用条件(它不在我的OS X上-它只会使程序随机打印两次
45.0
或两次
75.0

除此之外,您应该真正使用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

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

除此之外,您应该真正使用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

我猜想
write
语句某种程度上是一种“隐式障碍”,即s.t。来自不同线程的不同write语句是逐行给出的,而不是乱码。您应该将
suma
添加到
private
子句中的列表中。您应该真正使用OpenMP部分。我的猜测是
write
语句某种程度上是某种“隐式障碍”,即s.t。来自不同线程的不同write语句是逐行给出的,而不是乱码。您应该将
suma
添加到
private
子句的列表中。您应该真正使用OpenMP分区。