openmp
OpenMPの削減
サーチ…
#pragma omp reduction節を使用したPIの近似
h = 1.0 / n;
#pragma omp parallel for private(x) shared(n, h) reduction(+:area)
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
この例では、各スレッドは反復カウントのサブセットを実行します。各スレッドは、そのarea
ローカルプライベートコピーを持ち、パラレル領域の最後には、すべて領域の最終値を生成するために加算演算( +
)が適用されarea
。
#pragma omp criticalに基づく削減を使用したPIの近似
h = 1.0 / n;
#pragma omp parallel for private(x) shared(n, h, area)
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
#pragma omp critical
{
area += (4.0 / (1.0 + x*x));
}
}
pi = h * area;
この例では、各スレッドは反復回数のサブセットを実行し、共有変数area
原子的に累積します。これにより、失われた更新がないことが保証されます。
#pragma atomicに基づく還元を用いたPIの近似
h = 1.0 / n;
#pragma omp parallel for private(x) shared(n, h, area)
for (i = 1; i <= n; i++)
{
x = h * (i - 0.5);
#pragma atomic
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
この例では、各スレッドは反復回数のサブセットを実行し、共有変数area
原子的に累積します。これにより、失われた更新がないことが保証されます。指定された操作( +=
)は原子的に実行できるので、ここでは#pragma atomic
を使用できます。これは#pragma omp critical
使用法と比較して読みやすさを簡素化します。
PIの近似による#pragma omp reduction手作り
h = 1.0 / n;
#pragma omp parallel private(x) shared(n, h)
{
double thread_area = 0; // Private / local variable
#pragma omp for
for (i = 1; i <= n; i++)
{
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
}
pi = h * area;
スレッドは#pragma omp parallel
生成され#pragma omp parallel
。各スレッドには、その部分的な追加を格納する独立した/専用のthread_area
があります。次のループは、 #pragma omp for
を使用してスレッド間で分散さ#pragma omp for
ます。このループでは、各スレッドが独自のthread_area
を計算し、このループの後、コードは#pragma omp atomic
介して原子的に順次領域を集約し#pragma omp atomic
。
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow