はじめに
ここ数年で徐々に普及しているマルチコアプロセッサーの複数のコアを活用するには、アプリケーションの並列化が必要です。インテルでは、今後求められる並列プログラミングをより容易に行えるよう、並列化をサポートするコンパイラーやライブラリーなどのソフトウェア開発製品を提供しています。今回は対称行列の三重対角化を使い、並列化を実装する方法を説明します。
「三重対角化」とは行列の対角成分とその両隣の副対角成分以外をすべて0とする変換です。これは行列の固有値を求める時に行われる処理で、いったん三重対角行列に変換してから固有値を求める方が高速な場合が多いことが知られています。
並列化の実装方法として、今回は、
- インテル C++コンパイラーの自動並列化機能を使用した場合
- インテル スレッディング・ビルディング・ブロックを使用した場合
- インテル マス・カーネル・ライブラリーを使用した場合
の3パターンに大きく分けて説明し、実際の実行時間を比較しています。また、この中ではインテル コンパイラー ver11.0でサポートしているラムダ関数と、2種類のインテル マス・カーネル・ライブラリーの関数を紹介しています。
サンプルコードの概要
記事に添付しているサンプルコードの概要を説明すると、次のとおりです。
ハウスホルダー変換による三重対角化のプログラムをtridiag.ccに示します。関数tridiagonalization
が、三重対角化を行います。tridiagonalization
関数(図1)は、入力としてn*nの対称行列aとサイズnの配列を取り、行列aに三重対角化後の結果を入れて返します。また、dには行列の対角成分、eには副対角成分、tauには変換に利用した行列Qの成分を入れて返します。
void tridiagonalization(double a[], int n, double d[], double e[], double tau[]);
行列aとして、例えばa[i*n+j]と書くよりa[i][j]と書いた方が分かりやすいですし、コンパイラーが自動並列化できる場合があるなど、領域の連続した二次元配列を利用できれば良いのですが、C/C++では不可能なので、一次元配列として定義しています。(FORTRANでは可能です)。このため、aのi行j列を参照したい場合は、a[j*n+i]を利用します。
これを呼び出すためのメインルーチンは、サンプルファイルのeigen.ccを参照してください。
インテル C++コンパイラー、スレッディング・ビルディング・ブロックやインテル マス・カーネル・ライブラリーなど、インテルソフトウェア開発製品に関する詳細は、インテル株式会社のサイトをご参照ください。
「インテル C++コンパイラー 11.0 体験版」の入手方法
インテル C++コンパイラーは、30日間の無料体験版および各種マニュアルを提供しています(氏名やメールアドレスなどの入力が必要)。インテル C++コンパイラー Windows版プロフェッショナル・エディションの体験版には、本記事で紹介するライブラリー製品の体験版も含まれています。
体験版モジュールをダウンロードした後は、インストーラを起動しウィザードに従ってインストールを進めてください。使い始める方に最適なインストールガイド、入門ガイドも提供されています。
体験版を使用するには、下記の環境が必要です。詳細はインテル C++ コンパイラービルド環境の詳細をご覧ください。
- Microsoft Visual Studio
- OS
Visual C++.NET2003/Visual Studio.NET2003、Visual Studio 2005/2008
Windows XP SP3まで、Windows Vista、Windows Server 2003/Windows Server 2008
シリアルコンパイル
並列化を行わないでコンパイルを行います。その際、インテル C++コンパイラーが持つベクトル化(※1)を利用します。今回は、コマンドラインからコンパイラーを使用し、コンパイル時に使用するオプションには、一般的な最適化オプションである/O3とCore2アーキテクチャー用の最適化オプションである/QxT(または/QxSSSE3)を使用します。
まず、「IA-32アプリケーション対応用C++ビルド環境」を立ち上げます。これを立ち上げることでインテル C++コンパイラーやそれに付属するライブラリーがすぐに利用できるように環境が設定されたコマンドプロンプトが立ち上がります。ここで図2に示すコマンドを実行し、コンパイルします。
icl /O3 /QxT tridiag.cc eigen.cc /o tridiag.exe
コンパイルした結果を実行します。実行環境を表1に示します。
CPU | Core2Duo 2.4GHz |
OS | Windows XP SP2 |
ビルド環境 | Visual Studio 2005 |
コンパイラー | インテル C++ コンパイラー 11.0.066 プロフェッショナル・エディション |
このプログラムは引数に行列のサイズを指定すると、三重対角化にかかった時間が表示されます。ここでは行列のサイズとして2000を指定するために「tridiag 2000」とコマンドプロンプトに指定してプログラムを実行し、実行時間を表示させます。
ここでは、実行時間は18.0秒となりました。
ベクトル化の詳細については、インテル C++ コンパイラー 11.0 ユーザー・リファレンス・ガイド[自動ベクトル化の概要]をご参照ください。