Parallel processing FORTRAN OpenMP。并行Do循环不能有效工作
我用一种简单的蒙特卡罗方法计算了硬币的微分横截面。 因为其中一次迭代花费了大约4分钟,我想知道如果我能并行化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
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,刚刚尝试过,但都不起作用。请发布您的代码版本,它是您问题的最小复制者,我们可以编译和测试它。这是