1

小さな omp テストを書くだけでは、常に正しく動作するとは限りません。

#include <omp.h>
int main() {
  int i,j=0;
#pragma omp parallel
  for(i=0;i<1000;i++)
  {
#pragma omp barrier
    j+= j^i;
  }
  return j;
}

jこの例では、すべてのスレッドからの書き込みに対するの使用は正しくありませんが、

  • j の非決定論的な値のみが存在する必要があります

  • フリーズしています。

でコンパイルgcc-4.3.1 -fopenmp a.c -o gcc -static

4 コアの x86_Core2 Linux サーバーで実行:$ ./gccフリーズしました (4 ~ 5 回の高速実行で 1 回フリーズするなど)。

トレース:

[pid 13118] futex(0x80d3014, FUTEX_WAKE, 1) = 1
[pid 13119] <... futex resumed> )       = 0
[pid 13118] futex(0x80d3020, FUTEX_WAIT, 251, NULL <unfinished ...>
[pid 13119] futex(0x80d3014, FUTEX_WAKE, 1) = 0
[pid 13119] futex(0x80d3020, FUTEX_WAIT, 251, NULL                       
                        <freeze>

フリーズ (デッドロック) が発生するのはなぜですか?

4

3 に答える 3

4

各ループが独自のコピーを持つように i を非公開にしてみてください。

時間ができたので、説明してみます。デフォルトでは、OpenMP の変数は共有されます。変数を非公開にするデフォルトがある場合がいくつかあります。並列領域はそれらの 1 つではありません (そのため、ハイ パフォーマンス マークの応答は間違っています)。元のプログラムには、2 つの競合状態があります。1 つは i で、もう 1 つは j です。問題はiのものにあります。各スレッドはループを何回か実行しますが、i は各スレッドによって変更されるため、スレッドがループを実行する回数は不確定です。バリアが満たされるためにはすべてのスレッドがバリアを実行する必要があるため、すべてのスレッドが同じ回数だけバリアを実行するわけではないため、決して終了しないバリアにハングアップする場合が考えられます。

OpenMP 仕様 (OMP 仕様 V3.0、セクション 2.8.3 バリア コンストラクト) では、「検出されるワークシェアリング領域とバリア領域のシーケンスは、チーム内のすべてのスレッドで同じでなければならない」と明確に述べられているため、プログラムは非準拠であり、そのため、不確定な動作をする可能性があります。

于 2010-12-22T18:50:43.170 に答える
1

複数のスレッドから同じ場所に追加しようとしています。やろうとしていることを並行して行うことはできません。並行して合計したい場合は、それをより小さな断片に分割し、後でそれらを収集する必要があります。

a5b による更新: アイデアは正しいが、コードの間違った部分が発見されました。i変数は両方のスレッドによって変更されます。

于 2010-12-20T23:18:28.827 に答える
0

@ejd、私がプライベートとしてマークした場合、私のプログラムは準拠しますか?

申し訳ありませんが、この質問を見ました。技術的には、変数「i」をプライベートとしてマークすると、プログラムは OpenMP に準拠します。ただし、「j」には依然として競合状態があり、プログラムが準拠している間 (競合状態を持つ有効なケースがあるため)、「j」の値は指定されていません (OpenMP 仕様によると)。

以前の回答の 1 つで、バリア実装の速度を測定しようとしていると述べました。さまざまな OpenMP コンストラクトの結果を公開している、参照したい「ベンチマーク」がいくつかあります。1 つは Mark Bull (EPCC、エジンバラ大学) によって書かれ、もう 1 つ (Sphinx) は Lawrence Livermore National Labs (LLNL) によって書かれ、3 つ目 (Parkbench) は日本のコンピューティング パートナーシップによって書かれました。彼らはあなたにいくつかのガイダンスを提供するかもしれません.

于 2011-01-19T15:54:57.103 に答える