次のコードは、OpenMPを使用したリストランキングアルゴリズムの実装を示しています。このコードをプラグマなしで実行すると正しい結果が得られますが、プラグマをインクルードするとエラーが発生することがあります。出力は下部に表示されます。 2回目の出力が間違っていることがわかります。これはランダムに発生します。 プラグマを削除すると、私の出力は常に正しいです。プラグマを使用する方法にエラーがありますか、または私が紛失している依存関係がありますか? (順次出力される期待出力パラレル出力は、連続出力プログラムプリントDATA OK一致した場合。)OpenMPを使用したCのリストランキング実装 - 出力エラー
長さとスレッドの数である16
#define NSIZE 1
#define NMAX 16
int Ns[NSIZE] = {16};
int A[NMAX] = {14,13,5,16,11,10,9,12,0,8,7,15,4,3,2,1};
int B[NMAX + 1] = {0};
int S[NMAX + 1] = {0};
int Rp[NMAX + 1] = {0};
int next[NMAX+1] = {0};
for(int i = 1, j=0; i <= n; i++, j++)
{
B[i] = A[j];
}
int chunk = ceil(length/nthreads);
int i, j;
int tid;
//#pragma omp parallel num_threads(nthreads)
//{
//#pragma omp for schedule(dynamic, chunk) private(i)
for(i = 1; i <= length; i++)
{
Rp[i] = 1;
next[i] = S[i];
}
for(i = 1; i<=log2(length); i++)
{
#pragma omp parallel num_threads(nthreads) shared(Rp,next,chunk) private(j)
{
#pragma omp for schedule(dynamic,chunk)
for(j = 1; j <= length; j++)
{
if(next[j]!=0)
{
Rp[j] = Rp[j] + Rp[next[j]];
next[j] = next[next[j]];
}
}
}
}
OUTPUT:
./をa.outの - OK
Inpuパラレル
データから
(私はプログラムを最初に実行したときにこれが出力されました) t:14 13 5 16 11 10 9 12 0 8 7 15 4 3 2 1
シーケンシャル:6 10 4 8 3 15 1 13 0 14 2 12 9 5 11 7
パラレル:6 10 4 8 3 15 1 13 0 14 2 12 9 5 11 7
./a.out - (私はプログラムをもう一度実行した出力時)
パラレルデータ不一致から!
入力:14 13 5 16 11 10 9 12 0 8 7 15 4 3 2 1
シーケンシャル:6 10 4 8 3 15 1 13 0 14 2 12 9 5 11 7
パラレル:6 10 4 8 3 15 1 13 0 10 2 12 9 5 11 7
./a.out - (私はプログラムを三度目を実行した出力)
パラレル
データからOK
入力:14 13 5 16 11 10 9 12 0 8 7 15 4 3 2 1
シーケンシャル:6 10 4 8 3 15 1 13 0 14 2 12 9 5 11 7
パラレル:6 10 4 8 3 15 1 13 0 14 2 12 9 5 11 7
実際の[mcve]を含めるように質問してください。 'Rp'、' next'、 'S'はどこに定義されていますか?実際のエラーや予期しない出力は何ですか? (実際の出力と期待される出力を含めてください) –
競合条件は次のとおりです: 'next [j] = next [next [j]];'。実際には、これは 'j'ループを移動する順番によって決まります。並列化しようとすると順序が変わり、結果を変更する可能性があります。 – Gilles
@Gilles返事をありがとう。私はクリティカルな領域にifループを置くことで競合状態を解消しました。しかし、これは、現在、効率的にアルゴリズムをシーケンシャルに実行していることを意味します。レースを取り除くことができる他の方法はありますか(私はアルゴリズムを変更したくありません)。 – kumar