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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/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
Fortran 并行子程序性能差_Fortran_Openmp - Fatal编程技术网

Fortran 并行子程序性能差

Fortran 并行子程序性能差,fortran,openmp,Fortran,Openmp,我试图并行化下面的代码;然而,当它在主程序上执行时,似乎没有明显的加速。我在另一个程序上测试了相同的子例程,运行时间甚至比串行代码还要长 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

我试图并行化下面的代码;然而,当它在主程序上执行时,似乎没有明显的加速。我在另一个程序上测试了相同的子例程,运行时间甚至比串行代码还要长

      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

所以你有点像

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次。这会占用你所有的跑步时间。您看到的所有运行时间增加都是这种同步。

欢迎。你是如何测量时间的?别忘了带枪,谢谢你,弗拉基米尔。我在Linux中使用内置函数测量时间。第一次我通过插入随机数来运行这个子程序,我得到了4分钟44分钟的实时时间和用户时间。然而,串行代码给了我大约3分钟的时间,所以结果并不理想。第二次我用一个20页的超级复制程序长的主代码运行这个子程序时,我得到了大约13分钟的实时和用户时间。我猜第二次代码实际上并没有并行化,因为用户时间并没有明显大于实时时间。我说的对吗?我不能复制粘贴我的代码在这里我粘贴的时候会搞砸:(((程序施密德整数大小参数(大小=100)双精度::a(大小,大小),b(大小,大小),c(大小,大小),d(大小,大小)整数i,j,k外部旋转do i=1,大小do j=1,大小a(i,j)=dble(abs sqrt((实(i+j)/2+1)+400)-30)*12)b(i,j)=dble(i*j**3*abs(i-j)-22)c(i,j)=dble(a(j,i)*b(i,j)*(a(i,j)-b(i,j))/23)d(i,j)=dble((a(i,j)-a(j,i)+b(i,j)*b(j,i)-c(i,j)**2-900)do k=1,尺寸调用旋转(a,b,尺寸,尺寸,尺寸,尺寸,尺寸,尺寸,k,a(i,k),-a(i,k+1)调用旋转(c,尺寸,尺寸,尺寸,尺寸,尺寸,k),-1)enddo enddo enddoVladimir,实际上我想知道并行代码的慢是不是因为“共享变量”部分的信息过载。因为为了循环可以为矩阵的元素分配新的值,矩阵需要具有“共享”类型.然而,当矩阵太大时,这会减慢我的程序吗?哦,这绝对是有道理的!谢谢弗拉基米尔,我来自加拿大魁北克的问候,哈哈哈:)