0

次のようなシナリオがあります。

for (i = 0; i < n; i++)  
{  
  for (j = 0; j < m; j++)  
{  
  for (k = 0; k < x; k++)  
  {  
     val = 2*i + j + 4*k  
     if (val != 0)  
     {  
      for(t = 0; t < l; t++)  
         {  
           someFunction((i + t) + someFunction(j + t) + k*t)  
         }  
      }  
   }  
}  
}

これがブロック A であると考えると、私のコードにはさらに 2 つの同様のブロックがあります。並列にしたいので、OpenMPプラグマを使いました。ただし、この場合、どの変数が共有され、プライベートになるかについて少し混乱しているため、並列化することはできません。内側のループでの関数呼び出しが sum += x のような演算である場合、削減句を追加できたはずです。一般に、入れ子になった for ループがあり、メインの操作を行う別の内部 for ループがある場合、OpenMP を使用してコードを並列化するアプローチはどのようになるでしょうか。並列領域を宣言してから、単純にプラグマ fors をブロックの前に置いてみましたが、間違いなくそこにポイントがありません!

ありがとう、サヤン

4

2 に答える 2

1

私はCよりもFortranプログラマーなので、CスタイルのOpenMPに関する知識は乏しく、構文はあなたに任せます。

ここでの最も簡単なアプローチは、おそらく(これは後で修飾します)最も外側のループを単純に並列化することです。デフォルトでは、OpenMPは変数iをプライベートと見なし、残りはすべて共有と見なします。これはおそらくあなたが望むものではありません、あなたはおそらく作りjkそしてtプライベートにもしたいと思うでしょう。あなたvalもプライベートが欲しいのではないかと思います。

ループのネスト(つまり)の下部にあるステートメントに少し戸惑っていますがsomeFunction...、これはまったく値を返さないようです。それは副作用によって機能しますか?

したがって、このすべてのコードを囲む並列領域を宣言する必要はなく、おそらく最も外側のループのみを並列化する必要があります。内部ループも並列化する場合、OpenMPインストールがそれらを無視するか、プロセッサーよりも多くのプロセスを生成するか、またはひどく不平を言うことに気付くかもしれません。

私はあなたのプログラム(フラグメント)が何をしているかについていくつかの仮定をしたので、あなたの最も簡単なアプローチはおそらく最も外側のループを並列化することだと言います。仮定が間違っている場合は、内部ループの1つを並列化することをお勧めします。確認すべきもう1つのポイントは、並列化するループの実行数が、使用するスレッドの数よりもはるかに多いことです。4スレッドでトリップカウントがたとえば7のOpenMP実行ループを使用したくない場合、ロードバランスは非常に悪くなります。

于 2010-04-19T11:01:29.863 に答える
0

おっしゃる通り、最も内側のステートメントは someFunction((i + t) + someFunction2(j + t) + k*t) になります。

于 2010-04-19T16:39:45.580 に答える