Я сделал расчет дифференциального сечения монет, используя простой метод Монте-Карло.Поскольку одна из итераций заняла около 4 минут, я подумал, будет ли быстрее, если я смогу распараллелить одну из do-loop's
.Код выглядит следующим образом:
program Executable
use nrtype
use omp_lib
implicit none
! Input Variables
integer(I4B) :: Iter_max = 6
integer(I4B) :: coins_max = 5
real(SP) :: Lx = 10.0
real(SP) :: Ly = 10.0
real(SP) :: R = 1.0
! Intern variables
integer(I4B) :: i,m,procs,threads
real(SP) :: ratio_conv, ratio_dens, density, ratio_flux
real(SP), dimension(5) :: CS_conv
real(DP) :: time
real(SP) :: start, finish
!Starts the calculation
time = omp_get_wtime()
procs = omp_get_num_procs()
threads = omp_get_max_threads()
print*, 'Processors', procs
print*, 'Threads', threads
!%%%%%%%%%%%%%%%%%% CONVERGENCE %%%%%%%%%%%%%%%%%%
open(1, file = 'Convergencia.dat')
do i = 1,Iter_max
ratio_conv = ratio_flux(Lx,Ly,R,i,5)
density = 5.0/(Lx*Ly)
CS_conv(i) = ratio_conv/density
write(1,*) 5**(i-1)*10**5, CS_conv(i)
if (i > 2) then
if (abs(CS_conv(i) - CS_conv(i-1)) < (1e-3)*CS_conv(i) .AND. & abs(CS_conv(i) - CS_conv(i-2)) < (1e-3)*CS_conv(i)) then
print*, 'Convergence achieved at i =',i
exit
else if (i == Iter_max) then
print*, 'Didn't achieve convergence'
exit
end if
end if
enddo
close(1)
call system('gnuplot Convergencia.gnu')
!%%%%%%%%%%%%%%%%%% DENSITY CHANGES %%%%%%%%%%%%%%%%%%
open(2, file = 'cociente_flujo_vs_densidad.dat')
!$OMP PARALLEL default(none) shared(coins_max,Lx,Ly,R,i) private(m,density,flux_dens)
!$OMP DO
do m = 1,coins_max
flux_dens = ratio_flux(Lx,Ly,R,i,m)
density = m/(Lx*Ly)
write(2,*) density, flux_dens
print*, 'Coins', m
enddo
!$OMP END DO
!$OMP END PARALLEL
close(2)
time = omp_get_wtime() - time
print*, 'Time simulation = ',time,' seconds.'
call cpu_time(start)
call system('gnuplot CS_pendiente.gnu')
call CPU_TIME(finish)
print*, 'Time regression', finish-start, 'seconds.'
end program
В основном это вызывает две подпрограммы, которые не работают параллельно и ранее не вызывали проблем.Распараллеливаемая часть, что она делает, это записывает в файл различные значения плотности и потоков «частиц».Поскольку все они независимы друг от друга, я намеревался сделать так, чтобы каждый поток выполнял цикл для другого значения m
.
. Проблема заключается в следующем: когда я запускаю один и тот же код без !$OMP PARALLEL DO
, я получаю правильные результаты, но это длится от 4 до 5 минут.Теперь, когда я добавляю !$OMP PARALLEL DO - !$OMP END PARALLEL DO
, кажется, что код работает нормально, но не в этом разделе.Я имею в виду, что первая часть кода выполнена, что дает тот же результат, что и непараллельная попытка, которую я сделал, но когда она достигает !$OMP... etc etc
, число потоков на моем компьютере назначается программе, но она не рассчитываетсячто-нибудь.На самом деле строка print*, 'Coins', m
не отображается в консоли, что означает, что программа вообще ничего не вычисляет.Программа работает в течение 10 минут, мой процессор загружается и выгружается вместе с заданием, и ничего не происходит, поэтому я останавливаю программу.
Я читал в некоторых сообщениях, что проблема может быть из-за команды cpu_time
, ноЯ удостоверился, что строки для этого были вне параллелизуемой части кода.Я также изменил !$OMP PARALLEL DO - !$OMP PARALLEL END DO
на !$OMP DO - !$OMP END DO
, поскольку видел оба примера, но это тоже не помогло.
Я использую MacOS и Eclipse IDE, и я добавил флаг -fopenmp
к созданию и привязке настроек программы.
Я буквально не знаю, что делаю неправильно, и что-нибудь поможет.
Заранее спасибо.