行列コピー関数の最適化|行列積高速化#21
この記事は、以下の記事を分割したものです。
[元の記事]行列積計算を高速化してみる
一括で読みたい場合は、元の記事をご覧ください。
コピー関数の最適化の手続きは、行列積カーネルの手続きとほとんど同じです。唯一の違いは、コピー元である行列のアライメントが不明なため、アライメントが揃っている場合とそうでない場合で場合分けする点くらいです。
最適化の手続き
(1)ベクトライズ、アセンブラ化
(2)プリフェッチの挿入
(3)ループシフト/命令順序の入れ換え
(4)アライメントの場合分け
手続きは以上の通りですが、まずベクトライズの設計を検討します。
21-1. ベクトル化の設計
まず、行列Bのコピー関数(転置なし)について考えます。
転置なしコピー関数は、よく見るとデータのロード順とストア順が異なります。そのため、転置なしにも関わらず、データの詰め替え処理が必要になります。N≧4の倍について、具体的には、下図のようになります。
N≧4の場合、全ての要素を入れ替えるには、2段かいの詰め替え処理が必要になってしまいます。処理コストが高いですが、致し方ありません。
さらに、N&2の場合について考えます。
N&2の場合は、4要素ずつコピーをするよりも、XMMレジスタを使って2要素ずつコピーした方が、詰め替え処理も少なくでき、効率的です。
この場合、詰め替え処理は1回で済みます。
N&1の場合は、ストライドアクセスがなくなるため、ロード順とストア順が一致します。そのため、特に詰め替え処理は必要ありません。
次に、行列Aのコピー関数(転置あり)のベクトル化を考えます。
転置ありコピー関数の場合は、実はデータのロード順とストア順が一致しています。つまり、詰め替え処理は特に必要ありません。そのため、M≧4、M&2、M&1の場合について、下記のようになります。
M≧4の場合は4要素ずつ、N&2の場合は2要素ずつ、N&1の場合は1要素ずつ処理していけば良いことになりました。
転置ありコピー関数の場合は、むしろストライドアクセスの方が難問かもしれません。
具体的な実装方法については、有料にさせていただきます。
次の記事
ここから先は
¥ 100
この記事が気に入ったらチップで応援してみませんか?