C言語でオレオレ行列積ルーチンを作るプロジェクト (その6)
今回はOpenMPを使って並列化してみました。
プログラム
プログラム全体は以下のGitHubリポジトリにあります。 今回利用するプログラムは、
main.c
とmy_dgemm05.c
です。
コンパイル
今回はiccを用いた。
$ icc -static -openmp -mavx -O3 main.c my_dgemm06.c -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas -lpthread -lrt
gccも試してみた。
$ gcc -static -fopenmp -mavx -O3 main.c my_dgemm06.c -I/opt/OpenBLAS/include -L/opt/OpenBLAS/lib -lopenblas -lpthread -lrt
gccで実行すると正しい結果が得られなかった。 おそらくOpenMPの使い方を正しく理解していないのだと思われる。
しかしiccでは必ず正しい結果が得られる。今回はiccで測定を行った。
実行結果
プログラムを5回実行した結果を以下に示します。
回数 | 秒 |
---|---|
1回目 | 4.584060 |
2回目 | 4.678453 |
3回目 | 4.636003 |
4回目 | 4.669771 (中央値) |
5回目 | 4.677864 |
OpenBLASを100%とした時の各ルーチンのスピードを以下の表にまとめる。
BLAS | 秒 | 比率 |
---|---|---|
OpenBLAS | 1.610352 | 100% |
Intel MKL | 2.014311 | 79.9% |
ATLAS | 3.169463 | 50.8% |
my_dgemm06 (今回) | 4.669771 | 34.5% |
my_dgemm05 | 6.410661 | 25.1% |
my_dgemm04 | 13.641321 | 11.8% |
my_dgemm03 | 14.768021 | 10.9% |
my_dgemm02 | 16.290370 | 9.89% |
my_dgemm01 | 283.428661 | 0.568% |
まとめ
今回は行列積ルーチンをOpenMPを使って並列化してみた。 初めてOpenMPを使ったのでまだまだ使い方に確信が持てていない。 特に、gccでコンパイルした時には正しく動作していないので、 何か指示文が足りていないのかなんかなんだろうと思う。 iccでうまく動くのは、OpenMPのバージョンが違って 仕様が変更されたからなのではないだろうか。多分。
どちらにせよ、まだまだ性能の改善の余地はありそうなので、 OpenMPの使い方の調査と並行させつつ行列積ルーチンの改善に 取り組んでいきたい。 最終的にATLASと同等の性能がでればうれしい。