0

並列ゾーンの終わりに向かって重要なステートメントを使用して、OpenMP でプライベート配列 (1 次元または 2 次元) を削減する最良の方法を見つけたいと思います。これは、要素がすべてのスレッドによってさまざまな時点でインクリメントされる配列を持つ問題を解決するためのものです。これは、並列ゾーン内で一時配列を宣言することで解決しました (つまり、一時配列は 0 で初期化され、次に並列ゾーン内でインクリメントされます。元の共有配列に追加され、最後にメモリから削除されます)。

これを解決するために、次のマクロを作成して、ある配列を別の配列でインクリメントします。

// This is in a frame.h file
static INT count,count2;

/* Increment 1-D array x by array y */
#define Arr1Inc(x,y,n)                       \
              { for(count=0;count<n;count++) \
                  x[count]+=y[count]; }

/* Increment 2-D array x by array y */
#define Arr2Inc(x,y,m,n)                                   \
              { for(count2=0;count2<m;count2++)            \
                  for(count=0;count<n;count++)             \
                     x[count2][count]+=y[count2][count]; }

これらのマクロの使用例は次のとおりです。

// This is at the end of my parallel zone
// d1nfcx and d2nft are shared arrays
// d1nfcx_tmp and  d2nft_tmp are private arrays
// mnodim and mnopo are the array sizes

#pragma omp critical (update_force)
{
  Arr1Inc(d1nfcx,d1nfcx_tmp,mnopo)
  Arr2Inc(d2nft,d2nft_tmp,mnodim,mnopo)
}
free(d1nfcx_tmp);
free(d2nft_tmp);

これは問題なく動作するように見えますが、動作させるには、並列ゾーンの開始時に count 変数と count2 変数をプライベートとして宣言する必要があります。削減を行うためのより良い方法はありますか?

私の配列はかなり大きくなる可能性があるため(> 100,000要素)、これを可能な限り効率的にする必要があることに注意してください。

ありがとう!

4

0 に答える 0