Unity 勉強メモ

ゲームエンジンのUnityを勉強するブログです。

C言語でオレオレ行列積ルーチンを作るプロジェクト (その2)

今回から前回の単純な行列積プログラムを最適化していきます。 今回適用する最適化はループの交換です。

プログラム

前回のプログラムでは、ループの順番がi-j-lの順番でしたが、 今回はi-l-jの順番になっています。 こうすることで、行列Cと行列Bへのメモリアクセスが連続になり 高速になることが期待できます。

プログラム全体は以下のGitHubリポジトリにあります。 今回利用するプログラムは、 main.cmy_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倍高速なプログラムが得られました。 まだまだ速くなる余地があるので頑張って行きたいとおもいます。