用Fortran实现OpenMP归约中的变量局部性
这是我的Fortran代码的一部分用Fortran实现OpenMP归约中的变量局部性,fortran,openmp,Fortran,Openmp,这是我的Fortran代码的一部分 iabcd=0 !$OMP PARALLEL DEFAULT(PRIVATE) SHARED(icheck,iv,HO,tnljm,H) !$OMP DO SCHEDULE(DYNAMIC) REDUCTION(+: iabcd) do ia=1,HO%NLEV do ib=ia+1,HO%NLEV do ic=1,HO%NLEV do id=ic+1,HO%NLEV if(tnljm%t(ia)+tnljm%t(ib
iabcd=0
!$OMP PARALLEL DEFAULT(PRIVATE) SHARED(icheck,iv,HO,tnljm,H)
!$OMP DO SCHEDULE(DYNAMIC) REDUCTION(+: iabcd)
do ia=1,HO%NLEV
do ib=ia+1,HO%NLEV
do ic=1,HO%NLEV
do id=ic+1,HO%NLEV
if(tnljm%t(ia)+tnljm%t(ib) .ne. tnljm%t(ic)+tnljm%t(id)) cycle
iabcd = iabcd + 1
H%ka(iabcd) = ia
H%kb(iabcd) = ib
H%kc(iabcd) = ic
H%kd(iabcd) = id
H%ME2BM(iabcd) = 0.d0
enddo
enddo
enddo
enddo
!$OMP END DO
!$OMP END PARALLEL
我可以在没有任何警告的情况下运行代码。但是,结果很奇怪,与不使用OpenMP的结果不同。代码有什么问题?谢谢。当使用
OMP DO REDUCTION(+:iabc)
时,每个线程创建自己的私有变量iabc
,并在循环中使用该变量,只有在处理完并行区域后,才会进行添加
就是进入,
H%ka(iabcd) = ia
H%kb(iabcd) = ib
H%kc(iabcd) = ic
H%kd(iabcd) = id
H%ME2BM(iabcd) = 0.d0
仅使用本地专用版本的iabc
,这与串行版本的代码不同
相反,您可以使用
OMP-CRITICAL
更新iabc
,因为您希望所有线程都使用相同版本的iabc
(当然,还可以共享iabc
)。然后,您还必须在关键区域内创建iabc
的私有副本,以便使用正确的iabc
更新H
。然而,这将降低并行化的效率,除非tnljm%t(ia)+tnljm%t(ib).ne。tnljm%t(ic)+tnljm%t(id)
几乎总是正确的 当使用OMP DO REDUCTION(+:iabc)
时,每个线程创建自己的私有变量iabc
,并在循环中使用该变量,只有在处理并行区域后,才会进行加法
就是进入,
H%ka(iabcd) = ia
H%kb(iabcd) = ib
H%kc(iabcd) = ic
H%kd(iabcd) = id
H%ME2BM(iabcd) = 0.d0
仅使用本地专用版本的iabc
,这与串行版本的代码不同
相反,您可以使用
OMP-CRITICAL
更新iabc
,因为您希望所有线程都使用相同版本的iabc
(当然,还可以共享iabc
)。然后,您还必须在关键区域内创建iabc
的私有副本,以便使用正确的iabc
更新H
。然而,这将降低并行化的效率,除非tnljm%t(ia)+tnljm%t(ib).ne。tnljm%t(ic)+tnljm%t(id)
几乎总是正确的 欢迎来到stackoverflow。如果代码不是很明显的话,你应该拿出一个简单的例子,解释一下你的代码应该做什么。欢迎来到stackoverflow。如果代码不是很明显的话,你应该拿出一个简单的例子,解释一下你的代码应该做什么。