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

新着トピックス

MKLのパフォーマンスを調べる - 高速フーリエ変換

 続いて、高速フーリエ変換(FFT)のパフォーマンスを確認してみよう。FFTは信号処理や画像/音声処理などの分野で多く用いられている処理で、データの周波数特性を分析するために使われる解析処理である。FFTを実装したフリーのライブラリとしては、GPLで提供されているFFTWがある。ここではその最新版であるFFTW Version 3.2と、MKLのフーリエ変換ライブラリを比較してみよう。

 FFTWは、マサチューセッツ工科大学(MIT)のMatteo Frigo氏とSteven G. Johnson氏によって開発されたライブラリで、各種Linux/UNIXおよびWindowsで利用できる。CPUが備えるSSEやSSE2、3dNow!、Altivecなどの数値演算機能を利用した高速な演算が可能なほか、任意サイズのデータに対してフーリエ変換/逆フーリエ変換の両方が行えるといった特徴を持ち、各種数値計算ツールなどでも多く採用されている。

 MKLに含まれるFFT関数はFFTWとの互換性はないものの、FFTWと同様のインターフェイスを持つラッパーライブラリのソースコードが付属しており、これを利用することでFFTWを簡単にMKLに置き換えることができる。今回はこのラッパーライブラリを使用してFFTWで行っていたプログラムのFFT処理部分をMKLに置き換え、処理時間がどのくらい変わるのか調べてみよう。

 なお、このラッパーライブラリはデフォルトでは「C:\Program Files\Intel\Compiler\11.0\066\cpp\mkl\interfaces\fftw3xc」ディレクトリにインストールされるのだが、ソースコードのみしか含まれていないため、ライブラリを利用するためにはコマンドラインでnmakeコマンドを実行してコンパイルする必要がある。Windows環境の場合、スタートメニューの「Intel Software Development Tools」内にある「IA-32 対応アプリケーション用 C++ ビルド環境」を実行してコマンドプロンプトを開き、下記のように実行すればよい。

 cd C:\Program Files\Intel\Compiler\11.0\066\cpp\mkl\interfaces\fftw3xc
 nmake lib32

 これにより「C:\Program Files\Intel\Compiler\11.0\066\cpp\mkl\ia32\lib\」ディレクトリ以下に「fftw3xc_intel.lib」というライブラリが作成される。あとは「C:\Program Files\Intel\Compiler\11.0\066\cpp\mkl\include\fftw」以下にある「fftw3.h」をC/C++ソースコード内でインクルードし、上記で作成したfftw3xc_intel.libと、MKLのライブラリ「mkl_intel_c.lib」および「mkl_intel_thread.lib」、「mkl_core.lib」、「libguide40.lib」をリンクすれば、FFTWを利用するプログラムをそのままMKLを使って動かすことができる。

FFTWとMKLの処理速度を比較する

 処理速度比較に使用するプログラムは指定したモノクロ画像に対して2次元のFFT処理を行うもので、幅3072ドット、高さ2304ドットの画像をFFT処理し、処理にかかった時間を測定するものだ(リスト2)。

リスト2 サンプルコードのFFT処理部分(抜粋)
  /* 作業用メモリを割り当て */
  in  = fftw_malloc(sizeof(fftw_complex) * width * height);
  out = fftw_malloc(sizeof(fftw_complex) * width * height);

  /* データを作業用メモリにコピー */
  for( n = 0; n  width*height; n++ ) {
    in[n][0] = (float)input_image_buf[n];
    in[n][1] = 0.0;
  }

  /* FFTエンジンを初期化 */
  p = fftw_plan_dft_2d(height, width, in, out, FFTW_FORWARD, FFTW_ESTIMATE);

  /* FFTを実行 */
  fftw_execute(p);

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

 なお、FFTWはWindows環境でもコンパイルできるが、GCC向けに最適化を行っているために他のコンパイラではコンパイルできなかったり、パフォーマンスが落ちるという問題があるようだ。そのため、今回はFFTWのWebサイトで配布されているバイナリ版DLLを使用した。

 テストでは、FFTWを使ったプログラムをGCC 4およびVisual C++ 2008でコンパイルしたものと、MKLを用いたプログラムをインテル C++ コンパイラーでコンパイルしたものを用い、それらの処理時間を比較した。それぞれのコンパイルはコマンドラインで下記のように行った。

GCCでのコンパイル:
 gcc-4.exe -L. -o fft1_gcc.exe -lfftw3-3 -lm -O3 -march=core2 fft1.c

Visual C++でのコンパイル:
 cl.exe /Ox /Oi /Ot libfftw3-3.lib /Fefft1_vc.exe fft1.c

 さて、それぞれの実行時間をまとめたものが表4である。MKLを使用したプログラムは、FFTWを使ったものと比べて約60%高速に動作するという結果となった。

表4 3072×2304サイズの画像のFFT処理にかかった時間
プログラム1回目2回目3回目平均
GCC 4 + FFTW1.576秒1.513秒1.513秒1.534秒
Visual C++ + FFTW1.326秒1.279秒1.263秒1.289秒
インテル C++ コンパイラー +MKL0.733秒0.873秒0.780秒0.795秒

 FFT処理についても先のBLASの例と同様、複数のCPUコアを使って並列処理を行うことで、高速な処理を実現しているようだ(図2)。