C言語でオレオレ行列積ルーチンを作るプロジェクト (その2)
今回から前回の単純な行列積プログラムを最適化していきます。 今回適用する最適化はループの交換です。
プログラム
前回のプログラムでは、ループの順番がi-j-l
の順番でしたが、
今回はi-l-j
の順番になっています。
こうすることで、行列Cと行列Bへのメモリアクセスが連続になり
高速になることが期待できます。
プログラム全体は以下のGitHubリポジトリにあります。 今回利用するプログラムは、
main.c
とmy_dgemm02.c
です。
コンパイル
$ clang -static -O3 main.c my_dgemm02.c -I/opt/OpenBLAS/include \ -L/opt/OpenBLAS/lib -lopenblas -lpthread -lrt
実行結果
プログラムを5回実行した結果を以下に示します。
回数 | 秒 |
---|---|
1回目 | 16.340387 |
2回目 | 16.243099 |
3回目 | 16.290370 (中央値) |
4回目 | 16.378146 |
5回目 | 15.879535 |
OpenBLASを100%とした時の各ルーチンのスピードを以下の表にまとめます。
BLAS | 秒 | 比率 |
---|---|---|
OpenBLAS | 1.610352 | 100% |
Intel MKL | 2.014311 | 79.9% |
ATLAS | 3.169463 | 50.8% |
my_dgemm2 | 16.290370 | 9.89% |
my_dgemm1 | 283.428661 | 0.568% |
まとめ
ループの順番をちょこっと入れ替えただけで、 前回の約17倍高速なプログラムが得られました。 まだまだ速くなる余地があるので頑張って行きたいとおもいます。