主题:强隐式迭代(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
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