OpenMP* サンプル

OpenMP サンプルは、マルチスレッド・アプリケーションの作成とコンパイルの方法を示します。

コンパイラーに付属しているその他のサンプルについては、「サンプル」を参照してください。

サンプルファイルと保存場所

ソース

場所

openmp_sample.c

Linux* および Mac OS*

<install-dir>/samples/openmp_samples/

Windows*

<install-dir>\samples\openmp_samples\

説明

このサンプルは、コンパイラー・オプションと 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
Copyright (C) Microsoft Corporation.  All rights reserved.

-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 スレッドだけが使用され、ランタイムが大幅に向上したことに注意してください。