我有我想要并行化的代码,但我发现我使用的线程数量给了我大约0.5倍的减速。例如,我使用4个线程,运行速度慢两倍。为什么OpenMP慢我的代码与线程数成比例
- 编辑:对不起,在这里有前面的程序错误的部分。
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!Compute Dynamic Structure Factor of Q,T=const
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
SUBROUTINE COMPUTE_SQ(i_vmax,ION_COUNT,ions,t2,lines,lf,rx,ry,rz,r,x,y,z,s,simtype,vmax,q)
IMPLICIT NONE
Integer*4, INTENT(IN) ::i_vmax,ION_COUNT,ions,t2,lines
Real*8, INTENT(IN) ::lf,vmax
Integer*4, INTENT(IN), DIMENSION(1:51200) ::rx,ry,rz
Real*4, INTENT(IN), DIMENSION(1:51200,0:1000) ::x,y,z
Real*8, INTENT(INOUT),DIMENSION(1:i_vmax) ::s
Complex*16,INTENT(INOUT),DIMENSION(1:i_vmax,2) ::r
Complex*16,INTENT(INOUT),DIMENSION(1:i_vmax,2) ::q
Real*8, DIMENSION(1:i_vmax) ::si,co
Integer*4 ::k,i,p_start,p_end
Real*8 ::dotprod,co_temp,si_temp
Character*5,INTENT(IN) ::simtype
!!!!!!RE-INITIALIZE VARIABLES
Do 300 k=1,i_vmax
!if (mag(k).gt.vmax) then
!cycle
!endif
co(k)=0
si(k)=0
co_temp=0
si_temp=0
write(*,*) vmax
300 continue
!!!!!!!!!!!!!!!!!!!!
if (simtype.eq.'pfrac') then
p_start=30721
p_end=51200
else if (simtype.eq.'nfrac') then
p_start=0
p_end=30720
else
write (*,*) 'simtype not specified'
endif
!!!!!!!!!!!!!!!!!!!!!!
Do 31 k=1,i_vmax
! if (mag(k).gt.vmax) then
! cycle
! endif
co_temp=0
si_temp=0
!$OMP PARALLEL DO PRIVATE(dotprod,Qcur,co_temp,si_temp)
Do 41 i=p_start,p_end
dotprod=(rx(k)*x(i,t2)+ry(k)*y(i,t2)+rz(k)*z(i,t2))*lf
co_temp=co_temp+COS(dotprod) !Qcur/Qavg
si_temp=si_temp+SIN(dotprod) !Qcur/Qavg
41 continue
!$OMP END PARALLEL DO
q(k,2)= cmplx(co_temp,si_temp)
r(k,2)=r(k,2)+q(k,2)
s(k)=s(k) +(q(k,1) * conjg(q(k,2)))
s(k)=s(k)/(p_end-p_start+1)**2
!r(k,2)=r(k,2)/(p_end-p_start+1)
31 continue
RETURN
END SUBROUTINE COMPUTE_SQ
这是相关代码的一部分。起初,我在整个子程序中都有OMP部分,但我认为他们都可能试图读取相同的值,并且正在减慢它的速度,但似乎并不是这样,因为它的速度相同,无论哪个循环它结束。
作为参考,内环是在约20000次迭代和外约1000
我使用英特尔编译器40年4月1日与标志-mcmodel =介质-shared-英特尔(因为它使用> 2GB的mem)和-openmp当然。我已经用1,2,4,8,16个内核尝试过了,每次内核的倍增时间让我有1.5倍的运行时间。
任何想法赞赏!
空行太多,注释过多的代码,没有足够的缩进。我认为这不会让你的代码变慢,但它肯定会让它无法阅读。 –
你可以发布实际的时间,以及内部循环与外部循环的时间为1线程运行? – steabert
对不起,我使用前4行,所以当我在这里发布时,所有确实已经结构化的东西都转移到了第四行。 – user1993893