FORTRAN-OpenMP。并行Do-loop无法有效工作

时间:2019-05-30 12:02:21

标签: parallel-processing fortran openmp gfortran

我使用简单的蒙特卡洛方法计算了硬币的微分截面。 因为其中一次迭代花费了大约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加载并卸载了任务,但什么也没有发生,所以我停止了该程序。

我在一些帖子中读到问题可能是由于cpu_time命令引起的,但我确保其行不在代码的可并行化部分之外。由于我已经看过两个示例,所以我也将!$OMP PARALLEL DO - !$OMP PARALLEL END DO更改为!$OMP DO - !$OMP END DO,但这都无济于事。

我正在使用MacOS和Eclipse IDE,并且在程序的构建和链接首选项中添加了标志-fopenmp

我从字面上不知道我在做什么错,任何事情都会有所帮助。

谢谢。

0 个答案:

没有答案