Show page source of インテル謹製の数値演算ライブラリ「MKL」を使ってプログラムを高速化_p2 #49575

[[PageNavi(NavigationList)]]



==== MKLのパフォーマンスを調べる - 行列演算 ====
 では、広く普及しているフリーのライブラリと、MKLのパフォーマンスの差はどの程度なのだろうか。まずは工学分野から金融分野まで広く使われている、行列演算のパフォーマンスを調査してみよう。

 広く普及している行列演算ライブラリとしては、「BLAS」および「LAPACK」と呼ばれるものがある。BLASは、ベクトルと行列に対する基本的な線形代数演算(四則演算)を行うもので、Netlibプロジェクト([http://www.netlib.org/ http://www.netlib.org/])によってFortranのソースコードおよびCインターフェイスが公開されているほか、各種スーパーコンピューターやUNIX向けの実装や、環境に合わせた最適化済みライブラリを作成する「ATLAS」([http://sourceforge.jp/projects/sfnet_math-atlas/ http://math-atlas.sourceforge.net/])という実装もある。また、LAPACKはBLASを利用した線形方程式ソルバーである。

 MKLにはこのBLASと互換性のある行列演算関数を備えているので、まずはMKLに含まれるBLASと、Netlib版BLASおよびATLASについて、そのパフォーマンスを比較してみよう。

====== ○MKLのBLASを使ってプログラムを書く''' MKLを使ったプログラムを書くのには、特に難しい点はない。通常のライブラリを使用する際と同じく、使用する関数を選択して対応するヘッダーファイルをインクルードし、適切なライブラリをリンクするだけである。Windows環境の場合、MKLのマニュアルはデフォルトでは「C:\Program Files\Intel\Compiler\11.0\066\cpp\Documentation\mkl」にインストールされる。PDF形式のリファレンスマニュアルについては日本語版が付属している('''図1 ======
)ほか、[http://www.xlsoft.com/jp/products/intel/perflib/mkl/index.html?sfwiki エクセルソフトのWebサイト]で日本語のインストールガイドや入門ガイドといったドキュメントが公開されている。

[[Thumb(a0935a719748060157b8e0068db0ccbc.png, caption=図1 MKLに付属するPDFマニュアル)]]

 また、MKLのヘッダファイル類は「C:\Program Files\Intel\Compiler\11.0\066\cpp\mkl\include」以下に、ライブラリは「C:\Program Files\Intel\Compiler\11.0\066\cpp\mkl\ia32\lib」(x86環境の場合)にインストールされる。Visual Studioを使用する場合、プロジェクト設定で「追加のインクルード・ディレクトリー」および「追加のライブラリー・ディレクトリー」にこれらを加えておく。さらに、「追加の依存ファイル」でMKLのライブラリ本体を指定する。通常は「mkl_intel_c.lib」および「mkl_intel_thread.lib」、「mkl_core.lib」、「libguide40.lib」の4つを指定すれば良い('''表1''')。

 なお、Netlib版BLASおよびATLASはMKLに含まれるBLASとまったく同一のインターフェイスを持つため、ソースコードについてはそのまま流用し、使用するヘッダーファイルとライブラリを変えて再コンパイルして、それぞれのライブラリを使用する実行ファイルを作成した。コンパイラにはすべてインテル C++ コンパイラーを使用している。

 また、Netlib版BLASおよびATLASはそれぞれソースコードでの配布となるため、それぞれが推奨しているGCCでコンパイルを行ってライブラリを作成した。


==== テスト結果はMKLが圧倒的なパフォーマンスを見せる ====
 今回使用したテストプログラムは500×500の行列同士の乗算を100回繰り返すというもので、clock()関数を用いてプログラム実行直後と終了直前の時刻を取得し、その経過時間を測定した('''リスト1''')。ここで使われている「cblas_dgemm」という関数がBLASの行列乗算関数である。なお、GCC 4でのBLASのコンパイルでは「-O3 -march=core2」という最適化オプションを設定している。また、テスト環境には'''表2'''のようなCore 2 Duoマシンを使用した。

====== リスト1 サンプルプログラム(行列演算分のみ抜粋) ======


{{{
void prod_matrix_with_blas( double* matrixA, double* matrixB, double* matrixC, int dim ) {
  cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans,
              dim, dim, dim, 1.0,
              matrixB, dim,
              matrixC, dim, 0.0, matrixA, dim);
}
}}}

※サンプルプログラム全文は[//sourceforge.jp/magazine/08/12/25/1127251/2 こちら] さて、テスト結果であるが、次の'''表3'''のような結果となった。MKLを使ったプログラムは処理時間がATLASのほぼ半分と、非常に高いパフォーマンスを発揮している。

 また、それぞれのプログラムを実行した際のCPU負荷を見てみると、MKLを使ったプログラムを実行した際はCPUの2つのコア両方に負荷がかかっているのに対し、ATLASを使ったプログラムは片方のコアに負荷が集中しているのが分かる('''図2''')。つまり、MKLは処理を並列化して2つのコアで同時に処理するため、片方のコアしか使っていないATLASと比べてほぼ半分の時間で処理を完了できていると推測できる。

[[Thumb(06a5559568af00155fa24678653e4293.png, caption=図2 プログラム実行時のCPU負荷)]]



[[PageNavi(NavigationList)]]