チームメイトに OpenMP の簡単なプレゼンテーションを行うためのコード サンプルを準備していたときに、奇妙なケースを見つけました。最初に私は古典的なループを書きました:
void sequential(int *a, int size, int *b)
{
int i;
for (i = 0; i < size; i++) {
b[i] = a[i] * i;
}
}
for ディレクティブの正しい OpenMP の使用法は簡単です。int i
スコープを作成するには、宣言をスコープに移動するだけprivate
です。
void parallel_for(int *a, int size, int *b)
{
#pragma omp parallel for
for (int i = 0; i < size; i++) {
b[i] = a[i] * i;
}
}
しかし、次の関数を書いたときint j
、for ループ スコープ外で宣言した共有のために、他の 2 つの異なる結果が得られると予想していました。しかし、テスト フレームワークを使用すると、予期したエラーが表示されず、その関数の出力に誤った値が表示されます。
void parallel_for_with_an_usage_error(int *a, int size, int *b)
{
int j;
#pragma omp parallel for
for (int i = 0; i < size; i++) {
/*int*/ j = a[i]; //To be correct j should be declared here, in-loop to be private !
j *= i;
b[i] = j;
}
}
私はテスト用の完全なソースコードを持っています.VS'12とgcc(C++ 11を有効にして)でビルドしますhttp://pastebin.com/NJ4L0cbV
コンパイラが何をしているのか知っていますか? 偽の共有を検出しますint j
か?最適化ヒューリスティックによりループ内に移動しますか?
感謝