我有一个子程序“ serial”的串行版本和一个子程序“ paral”的并行版本。我正在使用openmp。当我调用串行时钟时,我测量的挂钟时间为0.475秒。当我称并行信号时,我测量的是墙上时钟时间0.09309秒。总加速= 5倍,出色的结果。但是当我尝试:
do jjj=1,10
call serial
end do
当我执行0.475 * 10 = 4.75秒时,我测量的挂钟时间为1.398秒。当我尝试相同的循环,但使用“ call paral”时,我测量了1.08秒。循环版本的总加速= 1.398 / 1.08 = 1.3X。不良结果。当串行子例程被多次调用时,它的伸缩性会很好。当并行子例程被多次调用时,它会线性缩放(如预期的那样)。有关此的一些建议?我希望即使使用循环版本也可以保持5倍加速。我正在使用gfortran。谢谢
编辑: 这里我用来衡量性能的代码,请编译为: gfortran -fopenmp -fdefault-real-8 -fdefault-integer-8 -fdefault-double-8 -mcmodel =大代码。f
PARAMETER(KMM1=80, JM=500 , IMM1=80 )
COMMON/VEC/ AQX(IMM1,JM,KMM1),AQR(IMM1,JM,KMM1),
& ROVX(IMM1,JM,KMM1),RR(IMM1,JM,KMM1),
& FX(IMM1,JM,KMM1),XX(IMM1,JM,KMM1),
& SE(IMM1,JM,KMM1)
COMMON/VRB/ KMMM,JMMM,IMMM
include 'omp_lib.h'
DOUBLE PRECISION SEC,SEC1,SEC11,SEC22
KMMM=80
JMMM=500
IMMM=80
CALL OMP_SET_NUM_THREADS(4)
SEC1 = omp_get_wtime()
do JJJJ=1,10
CALL SERIAL
END DO
SEC = omp_get_wtime() - SEC1
WRITE(6,*) '#CPU SERIAL=', SEC, 'SECONDS.'
SEC11 = omp_get_wtime()
DO JJJJ=1,10
CALL PARAL
END DO
SEC22 = omp_get_wtime() - SEC11
WRITE(6,*) '#CPU PARALLEL=', SEC22, 'SECONDS.'
WRITE(6,*) 'SPEEDUP = ', SEC/SEC22
STOP
END
SUBROUTINE SERIAL
PARAMETER(KMM1=80, JM=500 , IMM1=80 )
COMMON/VEC/ AQX(IMM1,JM,KMM1),AQR(IMM1,JM,KMM1),
& RX(IMM1,JM,KMM1),RR(IMM1,JM,KMM1),
& FX(IMM1,JM,KMM1),XX(IMM1,JM,KMM1),
& SE(IMM1,JM,KMM1)
COMMON/VRB/ KMMM,JMMM,IMMM
DO K=1,KMMM
DO J=1,JMMM
DO I=1,IMMM
AX = RX(I,J,K)+RX(I,J,K+1)+RX(I+1,J,K)+RX(I+1,J,K+1)
AR = RR(I,J,K)+RR(I,J,K+1)+RR(I+1,J,K)+RR(I+1,J,K+1)
FX(I,J,K) = 0.25*(AX*AQX(I,J,K) + AR*AQR(I,J,K))
SE(I,J,K ) = 0.0
XX(I,J,K) = FX(I,J,K)
END DO
END DO
END DO
RETURN
END
SUBROUTINE PARAL
include 'omp_lib.h'
PARAMETER(KMM1=80, JM=500, IMM1=80 )
COMMON/VEC/ AQX(IMM1,JM,KMM1),AQR(IMM1,JM,KMM1),
& RX(IMM1,JM,KMM1),RR(IMM1,JM,KMM1),
& FX(IMM1,JM,KMM1),XX(IMM1,JM,KMM1),
& SE(IMM1,JM,KMM1)
COMMON/VRB/ KMMM,JMMM,IMMM
!$OMP PARALLEL DO DEFAULT(NONE) PRIVATE(AX,AR)
!$OMP+ SHARED(RX,RR,AQX,AQR,SE,FX,XX,JMMM,IMMM,KMMM)
DO K=1,KMMM
DO J=1,JMMM
DO I=1,IMMM
AX = RX(I,J,K)+RX(I,J,K+1)+RX(I+1,J,K)+RX(I+1,J,K+1)
AR = RR(I,J,K)+RR(I,J,K+1)+RR(I+1,J,K)+RR(I+1,J,K+1)
FX(I,J,K) = 0.25*(AX*AQX(I,J,K) + AR*AQR(I,J,K))
SE(I,J,K ) = 0.0
XX(I,J,K) = FX(I,J,K)
END DO
END DO
END DO
!$OMP END PARALLEL DO
RETURN
END
EDIT2:我进行了一些测试,似乎仅一次调用就看到了加速,这是由于使用了一些智能缓存所致。如果您将串行时序与Paral时序进行切换,则可以(仅通过调用)检查使用缓存带来的好处。实际的加速是在多次调用子例程时测得的。