Я хотел бы использовать 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
(должно быть что-то не так).
Что я сделал не так?
Используйте тег PTAG: Фортран] для всех Фортрана вопросов. Добавьте тег версии, где необходимо различать. Обратите внимание на количество людей, подписавшихся на [tag: fortran] и [tag: fortran95], и вы хотите, чтобы больше людей увидели ваш вопрос, не так ли? –
Почти верно сказать, что параллельные программы всегда приносят разные результаты своим последователям-кузенам. Конкретно о том, как результаты разные, из различий многое можно узнать. –
Попробуйте использовать заголовки, определяющие вашу проблему, а не только тему. Тема довольно хорошо определена тегами. –