Unity 勉強メモ

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

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

今回はOpenMPを使って並列化してみました。

プログラム

プログラム全体は以下のGitHubリポジトリにあります。 今回利用するプログラムは、 main.cmy_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と同等の性能がでればうれしい。