openmp
OpenMPの削減
サーチ…
備考
4つのバージョンはすべて有効ですが、削減のさまざまな側面を例示しています。
デフォルトでは、 reduction
節を使用する最初の構文が優先される必要があります 。これは、3つの選択肢のいずれかが検討される可能性のある問題が明示的に特定されている場合にのみ発生します。
PIの近似による#pragma omp reduction手作り
int i;
int n = 1000000;
double area = 0;
double h = 1.0 / n;
#pragma omp parallel shared(n, h)
{
double thread_area = 0; // Private / local variable
#pragma omp for
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
thread_area += (4.0 / (1.0 + x*x));
}
#pragma omp atomic // Applies the reduction manually
area += thread_area; // All threads aggregate into area
}
double pi = h * area;
スレッドは#pragma omp parallelで生成されます。各スレッドには、その部分的な追加を格納する独立した/専用のthread_areaがあります。次のループは、#pragma omp forを使用してスレッド間で分散されます。このループでは、各スレッドが独自のthread_areaを計算し、このループの後、コードは領域を原子的に順次集約します
#pragma atomicに基づく還元を用いたPIの近似
double area;
double h = 1.0 / n;
#pragma omp parallel for shared(n, h, area)
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
#pragma atomic
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
この例では、各スレッドは反復回数のサブセットを実行し、共有変数領域に原子的に累積します。これにより、失われた更新がないことが保証されます。指定された操作(+ =)は原子的に実行できるので、ここでは#pragma atomicを使用できます。これは#pragma omp criticalの使用法と比較して読みやすさを簡素化します。
#pragma omp criticalに基づく削減を使用したPIの近似
double area;
double h = 1.0 / n;
#pragma omp parallel for shared(n, h, area)
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
#pragma omp critical
{
area += (4.0 / (1.0 + x*x));
}
}
double pi = h * area;
この例では、各スレッドは反復回数のサブセットを実行し、共有変数領域に原子的に累積します。これにより、失われた更新がないことが保証されます。
#pragma omp reduction節を使用したPIの近似
int i;
int n = 1000000;
double area = 0;
double h = 1.0 / n;
#pragma omp parallel for shared(n, h) reduction(+:area)
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
この例では、各スレッドは反復カウントのサブセットを実行します。各スレッドは、その領域のローカルプライベートコピーを持ち、パラレル領域の最後には、すべて領域の最終値を生成するために加算演算(+)が適用されます。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow