我试图并行化以下代码;然而,当它在主程序上执行时,似乎没有显着的加速。我在另一个程序上测试了相同的子程序,运行时间比串行代码要长。
SUBROUTINE rotate(r,qt,n,np,i,a,b)
IMPLICIT NONE
INTEGER n,np,i
DOUBLE PRECISION a,b,r(np,np),qt(np,np)
INTEGER j
DOUBLE PRECISION c,fact,s,w,y
if(a.eq.0.d0)then
c=0.d0
s=sign(1.d0,b)
else if(abs(a).gt.abs(b))then
fact=b/a
c=sign(1.d0/sqrt(1.d0+fact**2),a)
s=fact*c
else
fact=a/b
s=sign(1.d0/sqrt(1.d0+fact**2),b)
c=fact*s
endif
!$omp parallel shared(i,n,c,s,r,qt) private(y,w,j)
!$omp do schedule(static,2)
do 11 j=i,n
y=r(i,j)
w=r(i+1,j)
r(i,j)=c*y-s*w
r(i+1,j)=s*y+c*w
11 continue
!$omp do schedule(static,2)
do 12 j=1,n
y=qt(i,j)
w=qt(i+1,j)
qt(i,j)=c*y-s*w
qt(i+1,j)=s*y+c*w
12 continue
!$omp end parallel
return
END
C (C) Copr. 1986-92 Numerical Recipes Software Vs94z&):9+X%1j49#:`*.
然而,当我使用Linux中的内置函数来测量时间时,我得到了:
real 0m12.160s
user 4m49.894s
sys 0m0.880s
与串行代码的时间相比,这是荒谬的:
real 0m2.078s
user 0m2.068s
sys 0m0.000s
答案 0 :(得分:1)
所以你有类似
的东西do i=1,n
do j=1,n
do k=1,n
call rotate()
end do
end do
end do
表示n = 100
并且您正在rotate
内部并行化两个简单的循环。
那是没有希望的。如果你想要不错的性能,你必须并行化尽可能最外层的循环。
rotate
内的循环中根本没有足够的工作,并且它被调用了太多次。你称它为1000000次,因此线程必须同步或重新启动2000000次。这需要你所有的运行时间。您看到的所有运行时间增加都是此同步。