我在数值求解器中的Fortran代码中使用OpenMP来帮助加速。我在循环中有一个循环,但是,我只是将内循环并行化,因为外循环的上限是10(mnum=10
)。我已按以下方式编写代码。
use omp_lib
use nuclearvars
implicit none
external speciesgenerationHe
real(kind=dp) :: t, siaabsorption, intabsorption, vacabsorption, Heemission, &
& Heabsorption, vacemission, Hemonomeremission, Hevacapsorption,tempdf
integer :: i,j,n,id,proc
real(kind=dp),dimension(n) :: y, ydot
...
proc = omp_get_num_procs()-1
do j=0,mnum
!$omp parallel do private(i,tempdf) num_threads(proc)shared(Px,Pm,Qx,Qm,Qvarr,Qi,f,xnum,mnum,ydot,j) &
!$omp reduction(+:vacabsorption,Heemission,Heabsorption,vacemission,siaabsorption) schedule(static)
do i=1,xnum
tempdf = (Px(i-1)*f(i-1,j)-Qx(i,j)*f(i,j)-Px(i)*f(i,j)+Qx(i+1,j)*f(i+1,j)) &
& +(Pm(i)*f(i,j-1)-Qm(j)*f(i,j)-Pm(i)*f(i,j)+Qm(j+1)*f(i,j+1))
siaabsorption=siaabsorption+Qi(i)*f(i,j)
vacabsorption=vacabsorption+Px(i)*f(i,j)
Heemission=Heemission+Qm(j)*f(i,j)
Heabsorption=Heabsorption+Pm(i)*f(i,j)
vacemission=vacemission+Qvarr(i+1,j)*f(i+1,j)
ydot(i+4+j*xnum)=tempdf
end do
!$omp end parallel do
intabsorption=intabsorption+Qi(1)*f(1,j)
Hemonomeremission=Hemonomeremission+(Qm(j)+Qm(1))*f(1,j)
end do
当我使用omp
行测试时,这会增加计算时间!内部数组最多为100(xnum=100
)。我使用的计算机使用的是AMD E1-1200处理器(只有2个内核/线程),所以我预计不会加速(尽管我计划将它移动到i5英特尔处理器)。但是,与串行运行相比,我会期望加速一点点速度?
我担心的是我没有有效地写它。在这种情况下,我认为omp reduction
是最好的选择吗?将ydot
和它所做的值分开(siaabsorption
等)到单独的循环中会使它变慢。