【发布时间】:2016-07-20 15:40:57
【问题描述】:
我想为这个单线程代码使用 OpenMP:
PROGRAM SINGLE
INTEGER, DIMENSION(30000)::SUMGRM
INTEGER, DIMENSION(90000)::GRI,H
REAL*8::HSTEP1X,HSTEP2X
REAL*8::TIME1,TIME2
!Just intiial value
DO I=1, 30000
SUMGRM(I)=I*3
END DO
DO I=1, 90000
GRI(I)=I
H(I)=0.5*I/10000
END DO
!Computing computer's running time (start) : for serial programming
CALL CPU_TIME(TIME1)
DO K=1, 50000
DO I=2, 30000
HSTEP1X=0.0
DO J=SUMGRM(I-1)+1, SUMGRM(I)-1
HSTEP2X=H(GRI(J))/0.99
HSTEP1X=HSTEP1X+HSTEP2X
END DO
HSTEP2X=H(GRI(SUMGRM(I)))/0.99
HSTEP1X=HSTEP1X+HSTEP2X
END DO
END DO
PRINT *, 'Results =', HSTEP1X
PRINT *, ' '
!Computing computer's running time (finish) : for serial programming
CALL CPU_TIME(TIME2)
PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)'
END PROGRAM SINGLE
如您所见,主要问题位于最内侧循环 (J),这也是最外侧循环 (I) 的函数。我试图像这样并行化这个程序:
PROGRAM PARALLEL
INTEGER, DIMENSION(30000)::SUMGRM
INTEGER, DIMENSION(90000)::GRI,H
REAL*8::HSTEP1X,HSTEP2X
REAL*8::TIME1,TIME2,OMP_GET_WTIME
INTEGER::Q2,P2
!Just intiial value
DO I=1, 30000
SUMGRM(I)=I*3
END DO
DO I=1, 90000
GRI(I)=I
H(I)=0.5*I/10000
END DO
!Computing computer's running time (start) : for parallel programming
TIME1= OMP_GET_WTIME()
DO K=1, 50000
!$OMP PARALLEL DO PRIVATE (HSTEP1X,Q2,P2)
DO I=2, 30000
HSTEP1X=0.0
Q2=SUMGRM(I-1)+1
P2=SUMGRM(I)-1
DO J=Q2, P2
HSTEP2X=H(GRI(J))/0.99
HSTEP1X=HSTEP1X+HSTEP2X
END DO
HSTEP2X=H(GRI(SUMGRM(I)))/0.99
HSTEP1X=HSTEP1X+HSTEP2X
END DO
!$OMP END PARALLEL DO
END DO
PRINT *, 'Results =', HSTEP1X
PRINT *, ' '
!Computing computer's running time (finish) : for parallel programming
TIME2= OMP_GET_WTIME()
PRINT *, 'Elapsed real time = ', TIME2-TIME1, 'second(s)'
END PROGRAM PARALLEL
我正在使用gfortran with -O3 -fopenmp,然后导出OMP_NUM_THREADS=... 并行程序运行得更快,但结果与单线程代码不同。通过串行程序我得到12.1212(它是正确的),通过并行我得到0.000(一定有问题)。
我做错了什么?
【问题讨论】:
-
几乎可以说并行程序总是产生与其串行表亲不同的结果。具体说明结果有何不同,从差异中可以学到很多东西。
-
请尝试使用标题来说明您的问题,而不仅仅是主题。主题由标签很好地定义。
-
@VladimirF:你什么意思?你的意思是我也想通过观看次数来获得人气?不,我从不打算让更多人了解我的问题,我真的不在乎。我只是想我会从一些专家那里得到最正确的答案。我什至不知道获得观看次数有什么好处,除非我可以有更大的机会从一些专家那里得到答案。你能告诉我,这个网站是否禁止像我一样标记更多?如果是这样,我很乐意将其删除。谢谢。
-
@HighPerformanceMark:不同之处在于:通过单个程序我得到 12.1212(它是真实的),通过并行我得到 0.000(一定有问题)。
标签: fortran openmp gfortran fortran95