Parallel processing 并行化don'时的三个嵌套do循环;t给出与串行代码相同的结果

Parallel processing 并行化don'时的三个嵌套do循环;t给出与串行代码相同的结果,parallel-processing,fortran,openmp,Parallel Processing,Fortran,Openmp,我需要用openmp 4.5并行化这段代码(fortran77) DO 700 K=1,KMM1 K1 = KB1(K) K2 = KB2(K) DO 700 J=2,JM JSB= JSBLK(J) J1 = JB1(J) J2 = JB2(J) DO 700 I=1,IMM1

我需要用openmp 4.5并行化这段代码(fortran77)

      DO 700 K=1,KMM1
          K1 = KB1(K)
          K2 = KB2(K)
          DO 700 J=2,JM
              JSB= JSBLK(J)
              J1 = JB1(J)
              J2 = JB2(J)
              DO 700 I=1,IMM1
                  I1 = IB1(I)
                  I2 = IB2(I)
                  DELTA = STORE(I,J,K)
                  B1CHG(I1,J1,K1) = B1CHG(I1,J1,K1) + DELTA
                  B2CHG(I2,J2,K2) = B2CHG(I2,J2,K2) + DELTA
                  SBCHG(JSB)      = SBCHG(JSB)      + DELTA
  700 CONTINUE
我用了简单的语句!OMP并行DO,!OMP END PARALLEL做前后代码和检查结果,但它们不一样。我已经用随机值初始化了向量KB1、KB2、JSBLK、JB1、JB2、IB1、IB2、STORE、B1CHG、B2CHG、SBCHG,在并行循环中,我对变量使用了不同的名称(例如STOREP而不是STORE),然后我检查STOREP==STORE,B1CHGP==B2CHG等等。。如果删除openmp pragma,结果是相同的。这是我用于比较和测试串行和并行版本的代码:


     PARAMETER(KMM1=10, JM=5 , IMM1=5  )

     COMMON/VEC/ KB1(KMM1),KB2(KMM1),JSBLK(JM),JB1(JM),JB2(JM),
    &            IB1(IMM1),IB2(IMM1),STORE(IMM1,JM,KMM1),
    &            B1CHG(IMM1,JM,KMM1),B2CHG(IMM1,JM,KMM1),SBCHG(JM)

     COMMON/PARVEC/  STOREP(IMM1,JM,KMM1),
    &            B1CHGP(IMM1,JM,KMM1),B2CHGP(IMM1,JM,KMM1),SBCHGP(JM)




     include 'omp_lib.h'




C---------------------------------------------------------------------     
C   INITIALIZING DUMMY ARRAYS
C RANDOM_NUMBER E' UNA SUBROUTINE DEL FORTRAN 95      
     CALL RANDOM_SEED()
     DO 701 K=1,KMM1

         CALL RANDOM_NUMBER(U)
         KB1(K)=FLOOR((KMM1+1)*U)

         CALL RANDOM_NUMBER(U)
         JH = 0 + FLOOR((KMM1+1)*u)
         KB2(K)=JH

         DO 701 J=2,JM

         CALL RANDOM_NUMBER(U)
         JH = 0 + FLOOR((JM+1)*u)
         JSBLK(J)=JH

         CALL RANDOM_NUMBER(U)
         JH =  0 + FLOOR((JM+1)*U)
         JB1(J)=JH

         CALL RANDOM_NUMBER(U)
         JH = 0 + FLOOR((JM+1)*U)
         JB2(J)= JH

         DO 701 I=1,IMM1

             CALL RANDOM_NUMBER(U)
             JH = 0 + FLOOR((IMM1+1)*U)
             IB1(I)=JH


             CALL RANDOM_NUMBER(U)
             JH = 0 + FLOOR((IMM1+1)*U)
             IB2(I)=JH

             CALL RANDOM_NUMBER(STORE(I,J,K))
             CALL RANDOM_NUMBER(B1CHG(I,J,K))
             CALL RANDOM_NUMBER(B2CHG(I,J,K))
             CALL RANDOM_NUMBER(SBCHG(J))

             STOREP(I,J,K) = STORE(I,J,K)
             B1CHGP(I,J,K) = B1CHG(I,J,K)
             B2CHGP(I,J,K) = B2CHG(I,J,K)
             SBCHGP(J)= SBCHG(J)

 701 CONTINUE

C---------------------------------------------------------------------
C PLOTTING THE INITIALIZED ARRAYS FOR VISUAL INSPECTION
     DO 702 K=1,KMM1
         WRITE(6,*) KB1(K),KB2(K) 
         DO 702 J=2,JM
             WRITE(6,*) JSBLK(J),JB1(J),JB2(J)
             DO 702 I=1,IMM1
                 WRITE(6,*) IB1(I),IB2(I),STORE(I,J,K)
                 WRITE(6,*) B1CHG(I,J,K)
                 WRITE(6,*) B2CHG(I,J,K)
                 WRITE(6,*) SBCHG(J)
 702 CONTINUE
C
C
C   NOW THE SERIAL/PARALLEL CODE COMPARING
C
c---------------------------------------------------------------------
C    ENTERING SERIAL REGION    



     SEC1 = omp_get_wtime ( )

     DO 700 K=1,KMM1
         K1 = KB1(K)
         K2 = KB2(K)
         DO 700 J=2,JM
             JSB= JSBLK(J)
             J1 = JB1(J)
             J2 = JB2(J)
             DO 700 I=1,IMM1
                I1 = IB1(I)
                I2 = IB2(I)
                DELTA = STORE(I,J,K)
                B1CHG(I1,J1,K1) = B1CHG(I1,J1,K1) + DELTA
                B2CHG(I2,J2,K2) = B2CHG(I2,J2,K2) + DELTA
                SBCHG(JSB)      = SBCHG(JSB)      + DELTA
 700 CONTINUE

     SEC = omp_get_wtime ( ) - SEC1
     WRITE(6,*) '#CPU SERIAL=', SEC, 'SECONDS.'

C---------------------------------------------------------------------
C     LEAVING SERIAL REGION


C---------------------------------------------------------------------
C    ENTERING PARALLEL REGION

     SEC1 = omp_get_wtime ( )

!$OMP PARALLEL DO

     DO K=1,KMM1
         K1 = KB1(K)
         K2 = KB2(K)
         DO J=2,JM
         JSB= JSBLK(J)
         J1 = JB1(J)
         J2 = JB2(J)

         DO I=1,IMM1
             I1 = IB1(I)
             I2 = IB2(I)
             DELTAP = STOREP(I,J,K)
             B1CHGP(I1,J1,K1) = B1CHGP(I1,J1,K1) + DELTAP
             B2CHGP(I2,J2,K2) = B2CHGP(I2,J2,K2) + DELTAP
             SBCHGP(JSB)      = SBCHGP(JSB)      + DELTAP
     END DO

     END DO
     END DO

!$OMP END PARALLEL DO

     SEC = omp_get_wtime ( ) - SEC1
     WRITE(6,*) '#CPU PARALLEL=', SEC, 'SECONDS.'


C---------------------------------------------------------------------
C     LEAVING PARALLEL REGION



C----------------------------------------------------------------------
C VERIFYING DATA CORRECTNESS 




     DO K=1,KMM1

         DO J=2,JM

             DO I=1,IMM1

                 IF(B1CHG(I,J,K).NE.B1CHGP(I,J,K)) THEN 
                    T=B1CHG(I,J,K)-B1CHGP(I,J,K)
                    WRITE(6,*) 'ERROR  ', T
                 END IF
                 IF(B2CHG(I,J,K).NE.B2CHGP(I,J,K)) THEN
                     WRITE(6,*) 'ERROR' 
                 END IF
                 IF(SBCHG(J).NE.SBCHGP(J)) THEN 
                     WRITE(6,*) 'ERROR'      
                 END IF
     END DO
     END DO
     END DO

     RETURN
     END

请注意缩进,您的代码几乎无法读取。如果您尝试的代码有问题,请向我们展示代码,向我们展示错误的结果和正确的结果。看见此外,对所有Fortran问题使用标记。缩进是可以的,这是非常非常古老的Fortran代码,它几乎存在于语句标签上。我知道你是非常友好的帮助我,这是我的负担,显示readeble代码,但重新缩进所有的代码是一种痛苦。过一会儿,我将发布测试代码。@VladimirF我想您不习惯旧的遗留代码。Fortran编译器将limit列设置为72,因此几乎从不进行缩进。我还是缩进了代码。你说你用随机数填充了IB1,IB2,JB1,JB2,KB1,KB2。这还不够好,因为随机数可能会导致重复值,因此当累积到B1CHG、B2CHG中时会出现竞争条件-这些需要标记为减少值,除非您可以确保IB1、IB2等中没有重复值。。另外,您使用随机数生成器的方式可能会导致值越界。当我阅读您的代码时,所有数组的下界都是1。您使用的随机数可能会生成零的条目。这些是不允许的。如果你不能保证不同的条目,你是说循环不是完全独立的,因此不能像你写的那样并行。这就是你需要缩进或类似缩进的原因。请注意缩进,你的代码几乎无法阅读。如果您尝试的代码有问题,请向我们展示代码,向我们展示错误的结果和正确的结果。看见此外,对所有Fortran问题使用标记。缩进是可以的,这是非常非常古老的Fortran代码,它几乎存在于语句标签上。我知道你是非常友好的帮助我,这是我的负担,显示readeble代码,但重新缩进所有的代码是一种痛苦。过一会儿,我将发布测试代码。@VladimirF我想您不习惯旧的遗留代码。Fortran编译器将limit列设置为72,因此几乎从不进行缩进。我还是缩进了代码。你说你用随机数填充了IB1,IB2,JB1,JB2,KB1,KB2。这还不够好,因为随机数可能会导致重复值,因此当累积到B1CHG、B2CHG中时会出现竞争条件-这些需要标记为减少值,除非您可以确保IB1、IB2等中没有重复值。。另外,您使用随机数生成器的方式可能会导致值越界。当我阅读您的代码时,所有数组的下界都是1。您使用的随机数可能会生成零的条目。这些是不允许的。如果你不能保证不同的条目,你是说循环不是完全独立的,因此不能像你写的那样并行。这就是为什么你需要减价或类似的价格。