OpenMP サンプルは、マルチスレッド・アプリケーションの作成とコンパイルの方法を示します。
コンパイラーに付属しているその他のサンプルについては、「サンプル」を参照してください。
ソース |
場所 | ||||
---|---|---|---|---|---|
openmp_sample.c |
|
このサンプルは、コンパイラー・オプションと OpenMP プラグマを組み合わせてマルチスレッド実行ファイルおよびシングルスレッド実行ファイルのコンパイルと実行を行う方法を示しています。-openmp (Linux および Mac OS) または /Qopenmp (Windows) コンパイラー・オプションをコンパイルコマンドに追加すると、マルチスレッド実行ファイルが生成されます。これを追加しない場合は、同じコードでシングルスレッド実行ファイルが生成されます。
マルチスレッドを実装すると、OpenMP データや同期化の制御を必要とせずに各スレッドが同時にいくつかの副行列の積を計算することが可能です。
サンプルでは、各積行列 c[i][j] の要素は、因子行列 a[i][k] と b[k][j] の固有の行と列から計算されます。アルゴリズムは OpenMP により、"i" 行インデックスを使用して最外ループを並列化します。
最外 "i" ループと中 "k" ループの両ループは、手動で 4 倍にアンロールします。最内 "j" ループは、積の列と因子行列を 1 つずつ繰り返します。
多くの場合、マルチスレッド・ソースでは大規模なスタックサイズが必要です。以下にリストされているコマンドは、サンプルソースのコンパイルに必要なスタックサイズとコマンドを示しています。Linux および Mac OS: コマンドは bash シェルを想定しています。
プラットフォーム |
コマンド |
---|---|
Linux |
ulimit -s unlimited icc -openmp -std=c99 openmp_sample.c |
Mac OS |
ulimit -s 64000 icc -openmp -std=c99 openmp_sample.c |
Windows |
icl /Qopenmp /Qstd=c99 openmp_sample.c /F256000000 |
コンパイラーは、ステータスメッセージを生成し、並列化された定義ループまたは領域を表示します。次の例は、典型的なメッセージです。(Windows のステータスメッセージには、リンクフェーズが含まれます。)
プラットフォーム |
ステータスメッセージ |
---|---|
Linux |
openmp_sample.c(109): (col. 5) remark: OpenMP 定義ループが並列化されました。 openmp_sample.c(116): (col. 5) remark: OpenMP 定義ループが並列化されました。 openmp_sample.c(96): (col. 3) remark: OpenMP 定義領域が並列化されました。 |
Windows |
openmp_sample.c(106): (col. 5) remark: OpenMP 定義ループが並列化されました。 openmp_sample.c(113): (col. 5) remark: OpenMP 定義ループが並列化されました。 openmp_sample.c(93): (col. 3) remark: OpenMP 定義領域が並列化されました。 Microsoft (R) Incremental Linker
Version 8.00.50727.42 -out:openmp_sample.exe -stack:256000000 |
マルチスレッド実行ファイルを実行します。
プラットフォーム |
コマンド |
---|---|
Linux および Mac OS |
./a.out |
Windows |
openmp_sample |
マルチスレッド実行ファイルにより、次のような結果が出力されます。
サンプル出力 |
---|
Using time() for wall clock time Problem size: c(600,2400) = a(600,1200) * b(1200,2400) Calculating product 5 time(s)
We are using 2 thread(s)
Finished calculations. Matmul kernel wall clock time = 12.00 sec Wall clock time/thread = 6.00 sec MFlops = 1440.000000 |
レポートされているスレッド数に注意してください。少なくとも 2 つのスレッドが使用されています。
Linux および Mac OS (bash): 実行ファイルでセグメンテーション違反が発生した旨のエラーメッセージが表示される場合は、スタックサイズが原因であると考えられます。スタックサイズの設定を確認してください。次のコマンドを入力します: ulimit -s
上記で作成された実行ファイルを削除し、次のコンパイルコマンドを入力します。-openmp (Linux および Mac OS) オプションまたは /Qopenmp (Windows) オプションは指定していないことに注意してください。
Linux および Mac OS: 最後にスタックサイズを設定してから、セッションを閉じた場合は、再度スタックサイズを指定してください。
プラットフォーム |
コマンド |
---|---|
Linux および Mac OS |
icc -std=c99 openmp_sample.c |
Windows |
icl /Qstd=c99 openmp_sample.c /F256000000 |
コンパイラーは並列化ループまたは領域についてのメッセージは生成しないことに注意してください。OpenMP サポートは無効ですただし、コンパイラーは無視された OpenMP プラグマのステータスメッセージを表示します。
シングルスレッド実行ファイルを実行します。
プラットフォーム |
コマンド |
---|---|
Linux および Mac OS |
./a.out |
Windows |
openmp_sample |
実行ファイルにより、次のような結果が出力されます。
サンプル出力 |
---|
Using time() for wall clock time Problem size: c(600,2400) = a(600,1200) * b(1200,2400) Calculating product 5 time(s)
We are using 1 thread(s)
Finished calculations. Matmul kernel wall clock time = 23.00 sec Wall clock time/thread = 23.00 sec MFlops = 751.304348 |
1 スレッドだけが使用され、ランタイムが大幅に向上したことに注意してください。