【问题标题】:Row major versus Column major layout of matrices矩阵的行主要与列主要布局
【发布时间】:2012-12-01 21:54:54
【问题描述】:

在编程密集矩阵计算时,是否有任何理由选择行优先布局而不是列优先布局?

我知道,根据所选矩阵的布局,我们需要编写适当的代码以有效地使用高速缓存来提高速度。

以行为主的布局似乎更自然、更简单(至少对我而言)。但是像 LAPACK 这样用 Fortran 编写的主要库都使用列主布局,所以做出这个选择肯定是有原因的。

【问题讨论】:

    标签: performance matrix fortran


    【解决方案1】:

    FORTRAN 旨在解决科学和工程问题。从科学的角度来看,以列为主的存储更为自然,因为一般的线性代数约定使用列向量并且通常将矩阵视为列向量的串联。在矩阵向量乘法中,列向量位于右侧(乘法后),连续矩阵在左侧进一步添加,例如B*(A*x)。 COBOL、PL/1 和 C 等语言将矩阵视为行记录的集合,因此对它们而言,行优先顺序更自然。

    在线性代数中,向量由其坐标表示:x = x[1]*e1 + x[2]*e2 + ... + x[n]*en 其中x[i] 是向量坐标,eii-th 基向量。在矩阵表示中,基向量是列向量。线性运算符A 然后作用于x,给出:

    y = A*x = A*{x[1]*e1 + x[2]*e2 + ... x[n]*en}
            = x[1]*(A*e1) + x[2]*(A*e2) + ... x[n]*(A*en)
    

    在矩阵表示中,线性运算符An 列组成,其中i 列是A 作用于i-th 基向量的结果,而A*x 则简单A 的列与 x 坐标的系数的线性组合。在 FORTRAN 中,这将是:

    ! Zero out the result vector
    DO k = 1,n
      y(k) = 0.0
    END DO
    
    ! Iterate over the columns of A
    DO i = 1,n
      ! Add the i-th column to the linear combination with a weight of x(i)
      w = x(i)
      DO k = 1,n
        y(k) = y(k) + w*A(k,i)
      END DO
    END DO
    

    这会自动优先使用 A 的列主要存储。这可能看起来很尴尬,但早在 50 年代,当 FORTRAN 诞生时,FMAC 硬件和寄存器优化并没有像现在这样流行。

    【讨论】:

    • 您将A*x 视为A 的列的线性组合。我将A*x 视为xArows 的点积向量。在您的示例中切换到先迭代k,然后再迭代i,您将获得一个支持A 的行主要存储的版本。
    • 我很久以前在一本关于 Fortran 历史的书中读到它。不幸的是,记忆已经溜走了,我不记得这本书的名字了,否则我会参考它。在任何情况下,列线性组合方法被证明是一个不错的选择,因为它可以在早期的矢量超级计算机上高效实现,而点积矢量需要能够执行水平求和的矢量单元。
    【解决方案2】:

    我看不出有什么不同。两者都是将多维矩阵转换为线性内存顺序的好方法。转换方程非常相似。

    还有 / 和 \ 。以及大端和小端。有人做出了选择,后来有人做出了另一个选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 2015-06-30
      • 2014-04-20
      相关资源
      最近更新 更多