1

ライフ ゲームのシーケンシャル バージョンを作成しましたが、OpenMP を使用して並列バージョンのコードを作成する必要がありますが、いくつか問題があります。誰かが私を助けることができれば、それはとてもいいことです. ありがとう。これが私のシーケンシャルコードです:

// Swapping the two grids   
 #define SWAP_BOARDS( b1, b2 )  do { \
 char* temp = b1; \
 b1 = b2; \
 b2 = temp; \
 } while(0)

// Simplifying access to grid elements
   #define BOARD( G, X, Y )  ((G)[NC*(X)+(Y)])

 char* sequential_game_of_life (char* outgrid, char* ingrid, 
       const int nrows, const int ncols, const int gens_max) {

  const int NC = ncols;
  int curgen, i, j;

 for (curgen = 0; curgen < gens_max; curgen++)
   {

  for (i = 0; i < nrows; i++)
{
  for (j = 0; j < ncols; j++)
    {
      const int inorth = mod (i-1, nrows);
      const int isouth = mod (i+1, nrows);
      const int jwest = mod (j-1, ncols);
      const int jeast = mod (j+1, ncols);

      const char neighbor_count = 
    BOARD (ingrid, inorth, jwest) + 
    BOARD (ingrid, inorth, j) + 
    BOARD (ingrid, inorth, jeast) + 
    BOARD (ingrid, i, jwest) +
    BOARD (ingrid, i, jeast) + 
    BOARD (ingrid, isouth, jwest) +
    BOARD (ingrid, isouth, j) + 
    BOARD (ingrid, isouth, jeast);

      BOARD(outgrid, i, j) = alivep (neighbor_count, BOARD (ingrid, i, j));
    }
}
  SWAP_BOARDS( outgrid, ingrid );
}
  return outgrid;
 }

これらの 3 つの for を並行処理する必要があることはわかっていますが、その方法がわかりません。

4

1 に答える 1

4

各世代への入力は前の世代であるため、外側のループは並列化できないと思います。そのため、順次式があります(少なくとも、小さな変更でそれを行うことはできません!)

行列などをトラバースするネストされたループの場合、私は単一のループを0から(あなたの場合)まで実行し、ループインデックスncol*nrowを見つけiてから実行することを好みます。j

このような:

// because you are running a parallel codes multiple times in a loop,
// it would be better to make the thread swarm first and schedule the
// tasks in each loop iteration, to avoid multiple creation and destruction
// of working threads
#pragma omp parallel
for (curgen = 0; curgen < gens_max; curgen++)
{
    #pragma omp for
    for (t = 0; t < nrows*ncols; t++)
    {
        int i = t / ncols;
        int j = t % ncols;
        const int inorth = mod (i-1, nrows);
        const int isouth = mod (i+1, nrows);
        const int jwest = mod (j-1, ncols);
        const int jeast = mod (j+1, ncols);

        const char neighbor_count = 
            BOARD (ingrid, inorth, jwest) + 
            BOARD (ingrid, inorth, j) + 
            BOARD (ingrid, inorth, jeast) + 
            BOARD (ingrid, i, jwest) +
            BOARD (ingrid, i, jeast) + 
            BOARD (ingrid, isouth, jwest) +
            BOARD (ingrid, isouth, j) + 
            BOARD (ingrid, isouth, jeast);

        BOARD(outgrid, i, j) = alivep (neighbor_count, BOARD (ingrid, i, j));
    }
    SWAP_BOARDS( outgrid, ingrid );
}

このコードを、1000世代にわたる1000x1000マトリックス上のデュアルコア2.53 GHz CPUを搭載したラップトップで実行したところ、69%高速化されました。

于 2012-12-12T19:05:13.400 に答える