回 帖 发 新 帖 刷新版面

主题:在OpenMP并行区内调用子函数,运算结果出错

不知道在并行区内调用的子函数的变量是如何算的(共享还是私有?)。我并行区内调用子函数之后,与串行执行的值完全不一样。下面是我的OpenMP并行程序:(前面计算结果和串行结果一样,下面显示调用函数后结果不一样的代码)
   !$OMP PARALLEL PRIVATE(iblock,k,WTK)
   !$OMP DO
   do iblock = 1,nblocks_clinic
   do k = 1,km
         .............................
         call hdifft(k, WTK, TMIX(:,:,iblock), UMIX(:,:,iblock), VMIX(:,:,iblock))
         if(iblock==3)then
             print*,WTK
         endif
         .............................
   end do
   end do
   !$OMP END DO
   !$OMP END PARALLEL

   上面打印的WTK值与串行执行完全不一样,检测hifft函数,主要出错代码部分是hdifft里面的一个合并函数
merge,这是Fortran95的函数,根据k < KMT(:,:,iblock) 合并 1和0两个矩阵
   WTK = merge(c1, c0, k < KMT(:,:,iblock))
   我研究了好久都没看出来为什么串行和openMP并行为啥执行就不一样了,求各位专家指导一下,非常感谢!!

回复列表 (共7个回复)

沙发

你要保证hdifft被同时调用的时候是线程安全的. 有些函数一开始设计就是串行没有考虑到将来被并行的情况所以可能会一个"公共"变量, 导致线程不安全.

板凳

嗯,我仔细看了hifft函数,他的公共变量都是以数组的形式出现,就是Array(:,:,iblock),每个线程读写的区域都以iblock分开了,而局部变量就是在函数内部定义的变量应该是每个线程都会有一份副本吧,所以感觉应该是线程安全的。

3 楼

那就不知道了. 有save属性的变量的话基本上现成就不安全. 凭你给的信息只能作出这样的推断, 至于具体就只能分析过代码才知道了.
尽量用比较新的编译器, intel之前的编译器里面有部分omp的bug. 我都汇报过几个了. 或者用gfortran, gfortran的bug修复快我在ivf遇到的bug在gfortran下都没.

4 楼

线程不安全一般是怎么体现?由于有共享变量的读写,而造成的线程不安全会影响到线程内其他的与共享变量无关的代码么?

5 楼

只要不是读写同一个内存变量就没有关系.
那些子函数如果是你自己写的就自己保证线程安全, 如果是别人或者函数库的, 请查阅别人的资料或者库资料. 
你确定不是线程安全问题那就找其他原因吧. 通过比较成熟的omp编译器编译计算出来的结果不会出现一对一错的情况.

6 楼

我当前用的编译器是intel的10.1.1.018,这个版本的编译器有你说的bug么?另外我系统里面还有gfortran 4.1.2,用这个会不会好点?

7 楼

我是刚开始使用的时候遇到的bug, 是ivf11. 不知道是intel在引入omp 3.0标准的时候导致的还是以前版本就有.
gfortran的是否好一点我也不清楚, 当时论坛里面的f2003兄帮我用gfortran测试的时候没有我发现的bug. 不过觉得4.1.2似乎太老了一点...

我来回复

您尚未登录,请登录后再回复。点此登录或注册