密行列計算のプログラミングにおいて、列優先レイアウトよりも行優先レイアウトを選択する理由はありますか?
選択したマトリックスのレイアウトに応じて、速度を上げるためにキャッシュメモリを効果的に使用するための適切なコードを記述する必要があることを私は知っています。
行優先のレイアウトは、(少なくとも私には)より自然で単純に見えます。しかし、Fortranで書かれたLAPACKのような主要なライブラリは、列の主要なレイアウトを使用するため、この選択を行った理由はいくつかあるはずです。
密行列計算のプログラミングにおいて、列優先レイアウトよりも行優先レイアウトを選択する理由はありますか?
選択したマトリックスのレイアウトに応じて、速度を上げるためにキャッシュメモリを効果的に使用するための適切なコードを記述する必要があることを私は知っています。
行優先のレイアウトは、(少なくとも私には)より自然で単純に見えます。しかし、Fortranで書かれたLAPACKのような主要なライブラリは、列の主要なレイアウトを使用するため、この選択を行った理由はいくつかあるはずです。
FORTRANは、科学的および工学的問題を解決するために設計されました。一般的な線形代数の規則では列ベクトルを使用し、行列を列ベクトルの連結として扱うことが多いため、列メジャーストレージは科学的な観点からより自然です。行列ベクトルの乗算では、列ベクトルは右側にあり(乗算後)、連続する行列が左側にさらに追加されB*(A*x)
ます。COBOL、PL / 1、およびCなどの言語は、行列を行レコードのコレクションとして扱うため、それらの言語では、行優先順位がより自然です。
線形代数では、ベクトルはその座標で表されます。x = x[1]*e1 + x[2]*e2 + ... + x[n]*en
ここでx[i]
、はベクトル座標でei
あり、はi
-番目の基底ベクトルです。行列表現では、基底ベクトルは列ベクトルです。線形演算子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)
行列表現では、線形演算子A
はn
列で構成されます。列は、 -番目の基底ベクトルに基づいて作用しi
た結果であり、の列との座標の係数の線形結合です。FORTRANでは、これは次のようになります。A
i
A*x
A
x
! 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
。厄介に思えるかもしれませんが、FORTRANが誕生した50年代には、FMACハードウェアとレジスタの最適化は現在ほど人気がありませんでした。
違いは見られません。どちらも、多次元行列を線形メモリ次数に変換するための優れた方法です。変換の式は非常に似ています。
/と\もあります。そして、大小のエンディアン。誰かが選択を行い、後で他の誰かが別の選択をしました。