Parallel processing 并行化don'时的三个嵌套do循环;t给出与串行代码相同的结果
我需要用openmp 4.5并行化这段代码(fortran77)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
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。您使用的随机数可能会生成零的条目。这些是不允许的。如果你不能保证不同的条目,你是说循环不是完全独立的,因此不能像你写的那样并行。这就是为什么你需要减价或类似的价格。