计算化学公社

标题: Fortran OpenMP求助 [打印本页]

作者
Author:
wxhwbh    时间: 2020-4-1 13:53
标题: Fortran OpenMP求助
本帖最后由 wxhwbh 于 2020-4-1 13:59 编辑

最近在学习并行计算,尝试把以前的程序用OpenMP改成并行的。原来程序大致如下:

  1. do itraj=1,nsim

  2. ......(初始条件设置)

  3. do itime=0,nstep

  4. ......(动力学演化部分)
  5. tr=(itime+1)*dt

  6.                 if(mod(itime,int(t/dt/ngrid))==0)then   !设置格点,每隔几个步长存储一次数据

  7.                     igrid=itime/int(t/dt/ngrid)+1

  8.                     pop1(igrid,itraj)=...
  9.                     pop2(igrid,itraj)=...

  10.                     td(igrid)=tr

  11.                 end if

  12. end do
  13. end do

复制代码

第一行do itraj=1,nsim其实就是不同的轨迹分别作演化,一共nsim条轨迹。不同轨迹之间是独立的,所以想把不同轨迹的计算分配给不同线程。由于是动力学演化,因此除了第一个循环外,剩下的部分在每个线程中都应该顺序执行(包括循环的部分,比如do itime=0,nstep部分)。我尝试了这么改:

  1. !$ call OMP_SET_NUM_THREADS(4)
  2. !$OMP PARALLEL DO DEFAULT(PRIVATE) SHARED(nsim,pop1,pop2,nstep)
  3. do itraj=1,nsim

  4. ......(初始条件设置)

  5. do itime=0,nstep

  6. ......(动力学演化部分)
  7. tr=(itime+1)*dt

  8.                 if(mod(itime,int(t/dt/ngrid))==0)then   !设置格点,每隔几个步长存储一次数据

  9.                     igrid=itime/int(t/dt/ngrid)+1

  10.                     pop1(igrid,itraj)=...
  11.                     pop2(igrid,itraj)=...

  12.                     td(igrid)=tr

  13.                 end if

  14. end do
  15. end do
  16. !$OMP END PARALLEL DO
复制代码

确实起到了并行的效果,但输出结果不对。存储结果的pop1,pop2只有igrid=1时有值。不太明白是什么原因,想问问这个程序应该怎么改呢?

作者
Author:
sobereva    时间: 2020-4-3 11:33
nstep、nsim都没必要特意设shared,因为它们并不会被改写
建议把所有private变量都直接用private(...)写明,default方式设置经常不奏效。
搞不清楚症结的时候可以在里面加入一些write(*,*)输出变量便于调试

作者
Author:
wxhwbh    时间: 2020-4-3 12:05
sobereva 发表于 2020-4-3 11:33
nstep、nsim都没必要特意设shared,因为它们并不会被改写
建议把所有private变量都直接用private(...)写明 ...

把除pop1,pop2以外其余会修改的变量都用private定义了。输出结果倒是没问题,可是程序变得更慢了。
我现在头几行如下:
  1. !$ call OMP_SET_NUM_THREADS(4)

  2.     !$ M=OMP_get_num_threads()

  3.     !$ write(*,*) M

  4.     !$OMP PARALLEL DO PRIVATE(P,R,j,p1,tr,theta1,theta2,xe,pe,td,itime,igrid,H) SHARED(pop1,pop2) SCHEDULE(DYNAMIC)
复制代码


OMP_get_num_threads报出的线程数一直是1。社长这个是什么原因呢?
作者
Author:
sobereva    时间: 2020-4-3 12:25
不用call OMP_SET_NUM_THREADS(4),而改成!$OMP PARALLEL DO ...后面加上NUM_THREADS(4)再试
作者
Author:
万里云    时间: 2020-4-3 13:11
推荐楼主用MPI,所有变量都是私有的,只能通过子程序显式交换数据。每个进程执行哪些任务也是显式指定的,比OpenMP这种隐式并行清晰得多。
作者
Author:
wxhwbh    时间: 2020-4-3 14:17
万里云 发表于 2020-4-3 13:11
推荐楼主用MPI,所有变量都是私有的,只能通过子程序显式交换数据。每个进程执行哪些任务也是显式指定的, ...

谢谢你。不过MPI关于fortran的资料不太多,一直没怎么看明白。
作者
Author:
wxhwbh    时间: 2020-4-3 14:40
sobereva 发表于 2020-4-3 12:25
不用call OMP_SET_NUM_THREADS(4),而改成!$OMP PARALLEL DO ...后面加上NUM_THREADS(4)再试

好像还是不行。而且我刚刚检查了一下结果,并行运行出的结果是不对的(按上面所有方法能输出的话结果都不对),串行结果是对的。实在不知道什么原因。
话说每次并行运行时总会跳出一个
OMP: Warning #181: OMP_STACKSIZE: ignored because KMP_STACKSIZE has been defined
会和这个有关系吗?

作者
Author:
niobium    时间: 2020-4-3 16:08
wxhwbh 发表于 2020-4-3 14:40
好像还是不行。而且我刚刚检查了一下结果,并行运行出的结果是不对的(按上面所有方法能输出的话结果都不 ...

那你把这个变量的值放大一点看看
作者
Author:
wxhwbh    时间: 2020-4-3 17:04
niobium 发表于 2020-4-3 16:08
那你把这个变量的值放大一点看看

可是我没有定义这个变量啊

作者
Author:
niobium    时间: 2020-4-3 18:27
程序变慢可能是你本身每个线程的任务都是瞬间完成的,所以并行反而慢了。如果说整个程序串行也就分分钟完成,就没必要写并行了。另外,你这种情况要确保是static方式分配任务(不过一般默认就是)
作者
Author:
wxhwbh    时间: 2020-4-3 20:48
niobium 发表于 2020-4-3 18:27
程序变慢可能是你本身每个线程的任务都是瞬间完成的,所以并行反而慢了。如果说整个程序串行也就分分钟完成 ...

我确实一条轨迹用不了多久。但如果步长取小了或者轨迹数变多了,计算速度还是会受影响。
现在主要还是想解决并行了计算结果不对的问题。
作者
Author:
niobium    时间: 2020-4-3 20:51
wxhwbh 发表于 2020-4-3 20:48
我确实一条轨迹用不了多久。但如果步长取小了或者轨迹数变多了,计算速度还是会受影响。
现在主要还是想 ...

那就是仔细检查每一个变量的private和share属性是否正确。凭我的感觉,你的share变量不止那几个
作者
Author:
wxhwbh    时间: 2020-4-3 22:13
niobium 发表于 2020-4-3 20:51
那就是仔细检查每一个变量的private和share属性是否正确。凭我的感觉,你的share变量不止那几个

我记得如果不定义变量是什么的话,默认都是shared吧?我只是把最后存储结果的两个数组作为了shared。

作者
Author:
sobereva    时间: 2020-4-4 04:52
wxhwbh 发表于 2020-4-3 14:40
好像还是不行。而且我刚刚检查了一下结果,并行运行出的结果是不对的(按上面所有方法能输出的话结果都不 ...

跟这个无关,这是设置OpenMP堆栈内存的

我强烈建议所有被修改的变量一律都明确自行指定private、shared。不要去相信“默认”,很多网页、书上说的关于默认的情况和实际并不相符。

PS:OpenMP在我来看比起MPI方便得多,还不需要用户有MPI环境,而且可以共享内存节约内存使用

作者
Author:
万里云    时间: 2020-4-5 15:28
wxhwbh 发表于 2020-4-3 14:17
谢谢你。不过MPI关于fortran的资料不太多,一直没怎么看明白。

可以参考C语言的API和教程,区别在个别参数上。




欢迎光临 计算化学公社 (http://bbs.keinsci.com/) Powered by Discuz! X3.3