FORTRAN-OpenMP.Параллельный Do-loop не работает эффективно - PullRequest
1 голос
/ 30 мая 2019

Я сделал расчет дифференциального сечения монет, используя простой метод Монте-Карло.Поскольку одна из итераций заняла около 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 к созданию и привязке настроек программы.

Я буквально не знаю, что делаю неправильно, и что-нибудь поможет.

Заранее спасибо.

...