openmpタスクを使用して、基本的なjacobi2d計算のタイル実行をスケジュールしようとしています。 jacobi2dにopenmpの依存節が依存関係を宣言していない
A(i、j)は
A(I-1、J)
A(I + 1、J)
A(I、から(i、j)の依存性がありますj-1)
A(i、j + 1)である。
depend節について私が理解するためには、依存関係を正しく宣言していますが、コードを実行している間は尊重されていません。私は以下の単純なコードをコピーしました。最初は私の推測では、一部のタイルの範囲外がこの問題を引き起こしている可能性があるため、修正しましたが、問題は解決しません(修正されたタイル範囲の長いコードはコピーしませんでした。最大)
int n=8,tsteps=2,b=4; //n - size of matrix, tsteps - time iterations, b - tile size or block size
#pragma omp parallel
{
#pragma omp master
for (t=0; t<tsteps; ++t)
{
for (i=0; i<n; i+=b)
for (j=0; j<n; j+=b)
{
#pragma omp task firstprivate(t,i,j) depend(in:A[i-1:b+2][j-1:b+2]) depend(out:B[i:b][j:b])
{
#pragma omp critical
printf("t-%d i-%d j-%d --A",t,i,j); //Prints out time loop, i,j
}
}
for (i=0; i<n; i+=b)
for (j=0; j<n; j+=b)
{
#pragma omp task firstprivate(t,i,j) depend(in:B[i-1:b+2][j-1:b+2]) depend(out:A[i:b][j:b])
{
#pragma omp critical
printf("t-%d i-%d j-%d --B",t,i,j); //Prints out time loop, i,j
}
}
}
}
}
だから私-1とj-1と範囲ビーイング(B + 2)から始まる依存性を宣言するとの考え方は、隣接するタイルはまた、あなたの現在のタイルの計算に影響を与えるということです。同様に、隣接するタイルが値を使用したときに、Aの値を上書きするだけで済む2番目のループセットについても同様です。
コードはopenmp 4.0をサポートするgcc 5.3を使用してコンパイルされています。
ps:上に宣言された配列の範囲は、依存グラフを作成する際に考慮する開始位置とインデックスの数を示します。
編集(Zulanのコメントに基づいて) - 内部コードを単純なprint文に変更したので、タスクの実行順序を確認するだけで十分です。理想的には、上記の値(4タイルしかないので)すべてのタイルは最初のprintfを完了し、次に2番目のタイルだけを実行します。しかし、コードを実行すると、命令が混在します。
なぜループで作業共有を使用しないのですか?最初のループでは 'B'から読み込むが、' A'に書き込む。 2番目のループでは 'A'に書き込み、' B'から読み込みます。パート1は最初に並行し、パート2は並行して実行します。 part1とpart2の間でスレッドを同期させるようにしてください(これは 'nowait'を使わない限り暗黙的に指定する必要があります)。 –
確かに条件はすべて間違っていますか? ii == 0を考えてください。これは0からまだ実行されています! = n-1ですが、範囲外のアクセスを生成するので、それを望んでいません。 –
@Zboson - これも可能です。タスクを使用すると、理想的なやや効率的な使い方ができますより小さいタスクは、より高い並列性を提供し、より少ない同期化が要求されます。 @ Jim。はい、あなたは正しいです、コードにエラーがあります。依存関係の問題はまだあります。 2つのinner iiおよびjj forループの前に1つの印刷を行い、printステートメントの順序が間違っています。私はこのプリントを批判的なプラグマに入れておくことを念頭に置いていました。 – hajmola