/openmp (OpenMP 2.0 サポートの有効化)
更新 : 2007 年 11 月
#pragmaomp を処理するようにコンパイラに指示します。
/openmp
解説
#pragma omp は、OpenMP ディレクティブ および OpenMP 句 を指定するために使用されます。コンパイルで /openmp が指定されていない場合、コンパイラは OpenMP 句および OpenMP ディレクティブを無視します。OpenMP Function 呼び出しは、/openmp が指定されていない場合でもコンパイラで処理されます。
/openmp でコンパイルされ、OpenMP ライブラリ を使用するアプリケーションは、Windows 2000 以降のオペレーティング システムでのみ実行できます。
/openmp および /clr を指定してコンパイルされたアプリケーションは、単一のアプリケーション ドメイン プロセスでのみ実行できます。複数のアプリケーション ドメインはサポートされていません。つまり、モジュール コンストラクタ (.cctor) は、実行時に、プロセスのコンパイルで /openmp が指定されているかどうか、およびアプリケーションを既定以外のランタイムに読み込もうとしているかどうかを検出します。詳細については、「appdomain」、「/clr (共通言語ランタイムのコンパイル)」、および「混在アセンブリの初期化」を参照してください。
/openmp および /clr を指定してコンパイルされたアプリケーションを既定以外のアプリケーション ドメインに読み込もうとすると、TypeInitializationException 例外がデバッガの外部でスローされ、OpenMPWithMultipleAppdomainsException 例外がデバッガでスローされます。
これらの例外は、次の場合にも発生することがあります。
プロセスが /openmp を指定してコンパイルされたアプリケーションを含めている、既定以外のアプリケーション ドメインに、/clr を指定し /openmp を指定しないでコンパイルされたアプリケーションが読み込まれている場合。
/clr アプリケーションを regasm.exe (アセンブリ登録ツール (Regasm.exe)) などのユーティリティに渡し、そのユーティリティがその対象アセンブリを既定以外のアプリケーション ドメインに読み込む場合。
共通言語ランタイムのコード アクセス セキュリティは、OpenMP 領域では機能しません。CLR コード アクセス セキュリティ属性を並列領域外で適用する場合、この属性は並列領域内では有効になりません。
Microsoft では、AllowPartiallyTrustedCallersAttribute または任意の CLR コード アクセス セキュリティ属性を使用して部分的に信頼される呼び出し元を許可する /openmp アプリケーションを作成しないことをお勧めします。
Visual Studio 開発環境でこのコンパイラ オプションを設定するには
プロジェクトの [プロパティ ページ] ダイアログ ボックスを開きます。詳細については、「方法 : プロジェクト プロパティ ページを開く」を参照してください。
[構成プロパティ] ノードを展開します。
[C/C++] ノードを展開します。
[言語] プロパティ ページをクリックします。
[OpenMP サポート] プロパティを変更します。
このコンパイラ オプションをコードから設定するには
- OpenMP を参照してください。
使用例
次の例は、スレッドプールを起動時と起動後に使用した効果をいくつか比較しています。x64、シングル コア、デュアル プロセッサの場合、スレッドプールの起動に 16 ミリ秒かかります。しかし、その後のスレッドプールの使用にかかる時間はごくわずかです。
/openmp を指定してコンパイルした場合、test2 への 2 回目の呼び出しは、スレッドプールの起動がないので、/openmp- を指定してコンパイルした場合よりも実行時間が長くなることはありません。100 万回反復すると、test2 の 2 回目の呼び出しで /openmp バージョンは /openmp- バージョンよりも高速になります。25 回の反復では、/openmp- バージョンも /openmp バージョンもクロック単位より小さくなります。
したがって、アプリケーション内のループが 1 つだけで、その実行時間が 15 ミリ秒未満 (コンピュータのオーバーヘッドの概算により変わる) である場合は、/openmp は適していないことがありますが、それより長い場合は、/openmp の使用を検討します。
// cpp_compiler_options_openmp.cpp
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
volatile DWORD dwStart;
volatile int global = 0;
double test2(int num_steps) {
int i;
global++;
double x, pi, sum = 0.0, step;
step = 1.0 / (double) num_steps;
#pragma omp parallel for reduction(+:sum) private(x)
for (i = 1; i <= num_steps; i++) {
x = (i - 0.5) * step;
sum = sum + 4.0 / (1.0 + x*x);
}
pi = step * sum;
return pi;
}
int main(int argc, char* argv[]) {
double d;
int n = 1000000;
if (argc > 1)
n = atoi(argv[1]);
dwStart = GetTickCount();
d = test2(n);
printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);
dwStart = GetTickCount();
d = test2(n);
printf_s("For %d steps, pi = %.15f, %d milliseconds\n", n, d, GetTickCount() - dwStart);
}