HPC/並列プログラミングポータルでは、HPC(High Performance Computing)プログラミングや並列プログラミングに関する情報を集積・発信しています。

新着トピックス

MKLのパフォーマンスを調べる - 行列演算

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

 広く普及している行列演算ライブラリとしては、「BLAS」および「LAPACK」と呼ばれるものがある。BLASは、ベクトルと行列に対する基本的な線形代数演算(四則演算)を行うもので、Netlibプロジェクト(http://www.netlib.org/)によってFortranのソースコードおよびCインターフェイスが公開されているほか、各種スーパーコンピューターやUNIX向けの実装や、環境に合わせた最適化済みライブラリを作成する「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)ほか、エクセルソフトのWebサイトで日本語のインストールガイドや入門ガイドといったドキュメントが公開されている。

 また、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)。

表1 使用するライブラリ
ライブラリ名説明
mkl_core.libMKLのコアライブラリ
mkl_intel_c.libcdeclインターフェイスライブラリ
mkl_intel_thread.libMKLが内部的に使用するスレッドライブラリ
libguide40.libMKLが内部的に使用する動的スレッド処理ライブラリ

 なお、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);
}

※サンプルプログラム全文はこちら

表2 テストプログラムのコンパイルおよび実行に使用したPCのスペック
項目スペック
OSWindows Vista Businness SP1
CPUCore 2 Duo E6550(2.33GHz)
メモリ2048MB

 さて、テスト結果であるが、次の表3のような結果となった。MKLを使ったプログラムは処理時間がATLASのほぼ半分と、非常に高いパフォーマンスを発揮している。

表3 行列演算ライブラリのパフォーマンス比較結果
ライブラリ1回目2回目3回目平均
MKL1.872秒1.95秒1.887秒1.903秒
ATLAS3.9秒3.9秒3.884秒3.895秒
BLAS16.13秒16.099秒16.13秒16.120秒

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