回 帖 发 新 帖 刷新版面

主题:强隐式迭代(SIP)openmp流水线并行,开始几次迭代串并行结果还一致,后来并行怎就慢慢地发散了?

再向大家请教一个问题,强隐式迭代(SIP)的openmp流水线并行有什么特别吗?我做的时候前面几次(L=1~3)时,还和串行结果一致,后来就不一致了,偏差越来越大,以至于发散,请问什么原因?串并行结果不一致可以理解,导致最后并行发散就难以理解了。

      DO L=1,NSW(IFI)
        RESAB=0.
C      
C.....CALCULATE RESIDUAL VECTOR AND THE SUM OF ABSOLUTE VALUES
C
        DO I=2,NIM
        DO IJ=LI(I+IST)+2,LI(I+IST)+NJM
          RES(IJ)=SU(IJ)-AP(IJ)*FI(IJ)-AN(IJ)*FI(IJ+1)-
     *            AS(IJ)*FI(IJ-1)-AE(IJ)*FI(IJ+NJ)-AW(IJ)*FI(IJ-NJ)
        END DO
        END DO
C
        DO I=IOCS(K)+1,IOCS(K)+NOC(K)
          RES(IJL(I))=RES(IJL(I))-AR(I)*FI(IJR(I))
          RES(IJR(I))=RES(IJR(I))-AL(I)*FI(IJL(I))
        END DO
C
C.....FORWARD SUBSTITUTION
C
[color=FF0000][b]        omp_sync1=0
        omp_counter1=1  !
C$omp parallel private(omp_cur_thread)
        omp_cur_thread=omp_get_thread_num()
        omp_sync1(omp_cur_thread)=0
        
        if(omp_cur_thread>0)then !此if语句用于控制thread进入的循序
          do
C$omp flush(omp_sync1)
             if(omp_sync1(omp_cur_thread-1)>=omp_counter1)exit !前一个thread执行完一次循环后,该
                                         !thread跳出本循环,执行下面的迭代。
          end do
C$omp flush(RES,omp_sync1)          
        end if     
        
        DO I=2,NIM
C$omp do private(IJ) reduction(+:RESAB)        !采用omp do会对循环任务自动进行划分,如果指定各
                                          !thread的循环起始位置,不用omp do语句,只用omp parallel
                                          !也是一样,迭代次数多了,和串行结果的差别越来越大,然后发
                                          !散
        DO IJ=LI(I+IST)+2,LI(I+IST)+NJM
          RESAB=RESAB+ABS(RES(IJ))
          RES(IJ)=(RES(IJ)-LS(IJ)*RES(IJ-1)-LW(IJ)*RES(IJ-NJ))*LPR(IJ)
        END DO
C$omp end do nowait
         omp_sync1(omp_cur_thread)=omp_sync1(omp_cur_thread)+1 !加1后,下一个thread就可以跳出锁循环
C$omp flush(RES,omp_sync1)          
        END DO 
C$omp end parallel  [/b][/color]   
C  
        IF(L.EQ.1) RESOR(IFI)=RESAB
        RSM=RESAB/(RESOR(IFI)+SMALL)
C
C.....BACKWARD SUBSTITUTION AND CORRECTION OF VARIABLE
C
        DO I=NIM,2,-1
        DO IJ=LI(I+IST)+NJM,LI(I+IST)+2,-1
          RES(IJ)=RES(IJ)-UN(IJ)*RES(IJ+1)-UE(IJ)*RES(IJ+NJ)
          FI(IJ)=FI(IJ)+RES(IJ)
        END DO
        END DO
C
C.....CHECK CONVERGENCE OF INNER ITERATIONS
C
        IF(LTEST) WRITE(2,*)L,' INNER ITER, RESAB= ',RESAB
        IF(RSM.LT.SOR(IFI)) RETURN
C
      END DO

回复列表 (共15个回复)

11 楼

http://bbs.pfan.cn/post-294791.html
最后雪球说的那个.

12 楼

谢谢!看过你以前的帖子,你以前用intel mpi在linux上做过混编吧。这几天用你的方法添加了I_MPI_PIN_DOMAIN=omp环境变量后,加了2句omp语句后,mpi+openmp混合的并行比mpi并行慢了很多,就是用上次贴出来的的那个poisson0.f做的测试,不知道为什么?请问你当时的环境变量是怎么设置的啊?我怀疑是不是我的环境变量设置有问题。

下面是我做的环境变量的设置:
PATH=$PATH:/opt/intel/impi/4.0.3.008/ia32/bin
设置线程数:
export OMP_NUM_THREADS=2
设置线程绑定:
export I_MPI_PIN_DOMAIN=omp

13 楼

我们的服务器是linux的,所以一般都在windows下编写调试,最后移植到linux上运行. 其实真正做过mpi&omp混编的就只有一个. 单独的,使用omp的比较多. 现在双路单机的服务器性能也不错,懒得帮老板联网配置mpi了.

而且我觉得环境变量对运行效率的影响不是特别大,很多都是设置线程堆栈大小,线程数目,嵌套并行开关等等. 这些只是决定如何运行.

我想知道你机器配置怎样?是否跟你omp和mpi的数目相符. 还有就是,并行本身不一定意味着提速,线程和进程的运算量太小还不够抵消他们创建和关闭的开销的话,速度不升反降. 这个需要程序员处理好的.

例如楼顶的那段代码, 我第一次看的时候就觉得频繁使用了flush做线程同步和reduction做叠加(这个也需要线程间交互的)以及还要控制线程顺序. 我不知道这个算法里面运算量是否足够,不过就前面几点已经很大地影响了并行效果. poisson0.f那个我没怎么看.

14 楼

很高兴和你讨论这么久。问题基本上解决了。mpi/Openmp混编其实不是什么难题。就是把两种语句叠加起来就行了。今天我在单台四核linux系统上试了那个poisson0.f程序,发现混编运行还是能够加速的。用top命令查看,我用的是2进程2线程,正好四核,这时每个进程%cpu为199%(linux中%cpu最高为(N core)*100%);当系统还有别的进程在运行时,每个进程的%cpu要下降,这时运行时间要超过纯mpi,可见有有线程竞争时运行时间会变长。所以2核单台linux电脑上运行该代码时间会近延长一倍。

但是在windows系统上却不一样,我在单台4和win7系统上运行,混编的还是要比纯mpi的要长,另外,2台2核windows电脑联网,运行那个2进程2线程程序,每个电脑的进程的%cpu为60~70%,还有余量,但是最后运行时间还是要超过纯mpi,我猜想是不是windows系统不适合做混编程序的运行。

我也是要毕业的人啦,研究差不多到此为止吧,该把论文好好写写了。希望以后能常联系

15 楼

并行这块确实还有很多空间提升和积累经验. 我对windows的情况也不清楚,用得比较少. 所以我也是在边学边积累经验.
毕业才是首要事情, 以后有时间我还想去弄GPU并行, opencl的资料已经收集了不少就是抽不出时间系统地去了解. 有机会再交流.

我来回复

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