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
Matrix 更有效的矩阵块乘法方法_Matrix_Fortran - Fatal编程技术网

Matrix 更有效的矩阵块乘法方法

Matrix 更有效的矩阵块乘法方法,matrix,fortran,Matrix,Fortran,我写了一个关于块中矩阵乘法的小函数。但是我想知道是否有更有效的方法 subroutine blocks(a, b, c, blocksize) real(kind=dp), dimension(:,:), intent(in) :: a, b real(kind=dp), dimension(:,:), intent(out) :: c integer, intent(in) :: blocksize integer :: i,j,k,

我写了一个关于块中矩阵乘法的小函数。但是我想知道是否有更有效的方法


subroutine blocks(a, b, c, blocksize)
       real(kind=dp), dimension(:,:), intent(in)  :: a, b
       real(kind=dp), dimension(:,:), intent(out) :: c
       integer, intent(in) :: blocksize
       integer :: i,j,k,ii,jj,kk,n
       c = 0.0_dp 
       n = size(a,1)
   
       do jj=1,n,blocksize
        do kk=1,n,blocksize
           do ii=1,n,blocksize
            do j=jj,min(jj+blocksize-1,n)
             do k=kk,min(kk+blocksize-1,n)
              do i=ii,min(ii+blocksize-1,n)            
                c(i,j) = c(i,j) + a(i,k)*b(k,j)
              end do
             end do
            end do
          end do
        end do
   end do
   end subroutine  blocks

稍微的改进是避免重复计算
块大小-1

 subroutine blocks(a, b, c, blocksize)
   real(kind=dp), dimension(:,:), intent(in)  :: a, b
   real(kind=dp), dimension(:,:), intent(out) :: c
   integer, intent(in) :: blocksize
   integer :: i,j,k,ii,jj,kk,n,add
   c = 0.0_dp 
   n = size(a,1)
   add = blocksize - 1

   do jj=1,n,blocksize
     do kk=1,n,blocksize
       do ii=1,n,blocksize
         do j=jj,min(jj+add,n)
           do k=kk,min(kk+add,n)
             do i=ii,min(ii+add,n)            
               c(i,j) = c(i,j) + a(i,k)*b(k,j)
             end do
           end do
         end do
       end do
     end do
   end do
 end subroutine  blocks

除此之外,关于Fortran的使用,代码已经是最佳的(我知道,您在注释中相应地修改了链接到的循环)。

您的函数具体做什么?“在块中”是什么意思?目的何在?请注意,对于普通的矩阵乘法,您的代码永远不会像DGEMM这样的优化BLAS库子程序那么好。除非blocksize很小,否则BLAS将获胜。否则,它将至少取决于块大小、运行的硬件、使用的编译器、使用的编译器选项和可用的BLAS库的效率,以及月球的相位。要知道哪种解决方案是最好的,唯一的办法就是计时。但是我想尝试的4个想法是1)与BLAS比较2)与Matmul比较3)多线程4)手动展开k循环你好!我试着在块中做乘法,比如在这个链接中。但是我想知道是否有一种更有效的方法来实现它(使用更少的循环)。基本上,我想看看不同的乘法方法在时间上的差异。我尝试了直截了当的方法,我也尝试了BLAS和matmul,我现在尝试在块中进行乘法。链接将该算法作为一个有用的练习。我不反对学习和尝试学习。但不要指望你能打败那些已经开发了几十年并针对不同类型CPU进行了优化的库。请注意,大多数Linux发行版中预装的BLAS并不是最优化的,它是参考Fortran实现。这些优化的变体是OpenBLAS、GotoBLAS、ATLAS、MKL和其他…你好@VladimirF是的,我明白你的意思。也许我没有说清楚我的目的是什么。我在研究不同的乘法方法,以及它们如何影响速度。我看到了块乘法,我想知道是否有一种更有效的方法可以用更少的循环来实现。我所说的高效并不是指其他方法,而是指是否有更好的方法来编写/执行它