【问题标题】:Row major vs Column Major Matrix Multiplication行主要与列主要矩阵乘法
【发布时间】:2012-10-11 01:52:13
【问题描述】:

我目前正在开发一个尝试计算矩阵乘法的 C 程序。我已经通过循环遍历第二个矩阵的每一列来完成这项任务,如下所示。

我已将大小设置为 1000。

for(i=0;i<size;i++)
{
  for(j=0;j<size;j++)
  {
    for(k=0;k<size;k++)
    {
      matC[i][j]+=matA[i][k]*matB[k][j];
    }
  }
}

我想知道这个实现中存在什么问题的访问模式。是什么让行/列访问比另一个更有效?我试图从使用缓存的逻辑方面理解这一点。请帮助我理解这一点。非常感谢您的帮助:)

【问题讨论】:

    标签: c matrix row matrix-multiplication


    【解决方案1】:

    如果您正在谈论缓存的使用,那么您可能想要做一些称为循环平铺的事情。您将循环分成小块,以便循环的内部部分存储在缓存中(这些天相当大)。所以你的循环会变成类似的东西(如果你使用指针将矩阵传递给函数)

    for(j=0;j<size;j+=t)
        for(k=0;k<size;k+=t)
           for(i=0;i<size;i+=t)
              for(ii=i;ii<MIN(i+t,size);ii++)
                 for(jj=j;jj<MIN(j+t,size);jj++)
            {       
              var=*(c+ii * size+jj);    //Var is a scalar variable                     
              for(kk=k;kk<MIN(k+t,size);kk++)
                  {                      
             var = var + *(a+ii *size +kk) * *(bt +jj * size+ kk);          
                  }
              *(c+ii *size +jj) = var;
            }                       
    

    t 的值取决于您获得的加速比。它可以 t = 64,128,256 等等。您可以在这里使用许多其他技术。循环平铺只是一种有效利用缓存的技术。此外,您可以在发送到乘法函数之前转置 B 矩阵。这样,您将获得矩阵 B 元素的线性访问。为了向您解释更多 考虑

              A  --------   and B | | | |
                 --------         | | | |
                 --------         | | | | 
                 --------         | | | |
    

    在这里,您将始终考虑将 A 的第一行与 B 的第一列相乘。而且由于您使用的是C,我相信,CPU 需要额外的努力来读取矩阵 B 的所有列一个在内存里面。为了简化这些工作,您可以转置矩阵并获取矩阵B' 的行(本质上只是B 的列)并使用循环平铺缓存最大数量的元素以进行乘法运算。希望这会有所帮助。

    【讨论】:

    • 非常感谢!这个解释帮助我理解了它们的工作原理和它们的区别。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-27
    • 2018-11-27
    • 2019-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-20
    相关资源
    最近更新 更多