20

openmp を使用して 2 次元行列の平均を計算しようとしています。この 2 次元マトリックスは、実際にはイメージです。

私はデータのスレッド単位の分割を行っています。たとえば、Nスレッドがある場合は、Rows/ 行N数を などで処理thread0します。

私の質問は次のとおりです:「」でopenmp削減句を使用できます#pragma omp parallelか?

#pragma omp parallel reduction( + : sum )
{
    if( thread == 0 )
       bla bla code 
       sum = sum + val;

    else if( thread == 1 )
       bla bla code
       sum = sum + val;
}
4

2 に答える 2

30

はい、できます。reduction 句は、個々のワークシェアリング構造だけでなく、並列領域全体にも適用できますfor。これにより、たとえば、異なる並列セクションで実行される計算の削減が可能になります (コードを再構築するための推奨される方法)。

#pragma omp parallel sections private(val) reduction(+:sum)
{
   #pragma omp section
   {
      bla bla code
      sum += val;
   }
   #pragma omp section
   {
      bla bla code
      sum += val;
   }
}

forセクションを使用して再実装する代わりに、OpenMPワークシェアリング コンストラクトを使用して、チーム内のスレッド間でループの反復を自動的に分散することもできます。

#pragma omp parallel for private(val) reduction(+:sum)
for (row = 0; row < Rows; row++)
{
   bla bla code
   sum += val;
}

リダクション変数は非公開であり、それらの中間値 (つまり、parallel領域の最後でのリダクションの前に保持される値) は部分的なものであり、あまり有用ではないことに注意してください。たとえば、次のシリアル ループは (簡単に?) リダクション操作を使用してパラレル ループに変換することはできません。

for (row = 0; row < Rows; row++)
{
   bla bla code
   sum += val;
   if (sum > threshold)
      yada yada code
}

ここではyada yada code、 の累積値が の値を超えると、各反復で を実行sumする必要がありますthreshold。ループが並列に実行されると、合計が到達しても、 のプライベート値が にsum到達しない可能性がありthresholdます。

于 2012-11-08T14:13:03.730 に答える
0

あなたの場合、接頭辞の合計計算である 1 次元配列 (または2 次元配列)sum = sum + valとして解釈できます。val[i] = val[i-1] + val[i]val[rows][cols] = val[rows][cols-1] + val[rows][cols]

リダクションは前置和の解決策の 1 つです。リダクションは、'+'、'-'、'*'、'/' などの可換結合演算子に使用できます。

于 2014-05-07T20:14:53.237 に答える