Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用Fortran实现OpenMP归约中的变量局部性_Fortran_Openmp - Fatal编程技术网

用Fortran实现OpenMP归约中的变量局部性

用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

这是我的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) .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。如果代码不是很明显的话,你应该拿出一个简单的例子,解释一下你的代码应该做什么。