Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing FORTRAN OpenMP。并行Do循环不能有效工作_Parallel Processing_Fortran_Openmp_Gfortran - Fatal编程技术网

Parallel processing FORTRAN OpenMP。并行Do循环不能有效工作

Parallel processing FORTRAN OpenMP。并行Do循环不能有效工作,parallel-processing,fortran,openmp,gfortran,Parallel Processing,Fortran,Openmp,Gfortran,我用一种简单的蒙特卡罗方法计算了硬币的微分横截面。 因为其中一次迭代花费了大约4分钟,我想知道如果我能并行化do循环中的一个,它是否会更快。 代码如下 program Executable use nrtype use omp_lib implicit none ! Input Variables integer(I4B) :: Iter_max = 6 integer(I4B) :: coins_max = 5 real(SP) :: L

我用一种简单的蒙特卡罗方法计算了硬币的微分横截面。 因为其中一次迭代花费了大约4分钟,我想知道如果我能并行化
do循环中的一个
,它是否会更快。 代码如下

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

程序可执行文件
使用nrtype
使用omp_库
隐式无
! 输入变量
整数(I4B)::Iter_max=6
整数(I4B)::硬币最大值=5
真实值(SP)::Lx=10.0
真实值(SP)::Ly=10.0
真实值(SP)::R=1.0
! 实习变量
整数(I4B):i、m、进程、线程
真实(SP):比conv,比dens,密度,比通量
真实(SP),维度(5)::CS_conv
实时(DP)::时间
雷亚尔(SP):开始,结束
!开始计算
时间=omp\u get\u wtime()
procs=omp\u get\u num\u procs()
threads=omp\u get\u max\u threads()
打印*,“处理器”,程序
打印*,“线程”,线程
!%%%%%%%%%%%%%%%%%% 收敛性%%%
打开(1,文件='Convergencia.dat')
i=1,Iter_最大值
比值conv=比值通量(Lx,Ly,R,i,5)
密度=5.0/(Lx*Ly)
CS_conv(i)=比值_conv/密度
写(1,*)5**(i-1)*10**5,C_conv(i)
如果(i>2),则
如果(abs(CS_conv(i)-CS_conv(i-1))<(1e-3)*CS_conv(i).和。&abs(CS_conv(i)-CS_conv(i-2))<(1e-3)*CS_conv(i)),则
打印*,“在i=”时实现的收敛,i
出口
否则如果(i==Iter_max)那么
打印*,“未实现融合”
出口
如果结束
如果结束
结束循环
关闭(1)
呼叫系统('gnuplot Convergencia.gnu')
!%%%%%%%%%%%%%%%%%% 密度变化%
打开(2,文件='cociente\u flujo\u vs\u densidad.dat')
!$OMP并行默认值(无)共享(硬币最大值、Lx、Ly、R、i)私有(m、密度、流量)
!$OMP DO
do m=1,最大硬币数
通量密度=比通量(Lx,Ly,R,i,m)
密度=m/(Lx*Ly)
写入(2,*)密度,通量密度
打印*,“硬币”,m
结束循环
!$OMP端DO
!$端并联
关闭(2)
time=omp\u get\u wtime()-时间
打印*,“时间模拟=”,时间,'秒。“
呼叫cpu_时间(启动)
呼叫系统('gnuplot CS_pendiente.gnu')
呼叫CPU_时间(完成)
打印*,“时间回归”,完成-开始,“秒”
结束程序
这基本上调用了两个子例程,这两个子例程没有并行运行,以前也没有引起任何问题。可并行化部分的作用是在文件中写入不同的“粒子”密度和通量值。因为它们都是相互独立的,所以我打算做的是,每个线程以不同的
m
值运行循环

问题如下:当我运行相同的代码时,没有
$OMP PARALLEL DO
,我得到了正确的结果,但它会持续大约4到5分钟。现在当我添加
时$OMP并行DO-$OMP END PARALLEL DO
代码似乎工作正常,但不在该部分。我的意思是,代码的第一部分完成了,给出了与我所做的非并行尝试相同的结果,但是当它到达
时$嗯。。。etc etc
计算机中的线程数分配给程序,但它不计算任何内容。事实上,
print*,'Coins',m
一行并没有出现在控制台中,这意味着程序根本没有计算任何东西。程序运行10分钟,我的cpu与任务一起加载和卸载,但什么也没有发生,所以我停止了程序

我在一些帖子中读到,问题可能是由于
cpu\u time
命令造成的,但我确保它的行在代码的可并行部分之外。我也改变了
$OMP并行DO-$OMP平行端DO
$OMP DO-$OMP END DO
,因为我已经看到了这两个示例,但这两个示例都没有帮助

我使用的是MacOS和EclipseIDE,我已经在程序的构建和链接首选项中添加了标志
-fopenmp

我真的不知道我做错了什么,任何事情都会有帮助


提前感谢。

问题可能在文件编写中。只需将结果存储在一个大的共享数组中,您只有在退出并行循环后才在该文件上写入该数组。@Gilles,刚刚尝试过,但都不起作用。请发布您的代码版本,它是您问题的最小复制者,我们可以编译和测试它。这可能是文件编写中的问题。只需将结果存储在一个大的共享数组中,您只有在退出并行循环后才在该文件上写入该数组。@Gilles,刚刚尝试过,但都不起作用。请发布您的代码版本,它是您问题的最小复制者,我们可以编译和测试它。这是