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 个,但我不知道该怎么做。

4

1 回答 1

4

我认为外循环不能并行化,因为每一代的输入都是上一代,所以它有一个顺序公式(至少你不能做微小的变化!)

0如果嵌套循环遍历矩阵或类似的东西,我更喜欢从to ncol*nrow(在你的情况下)运行单个循环ij从循环索引中查找和查找。

像这样:

// 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 );
}

我在我的笔记本电脑上使用双核 2.53 GHz CPU 在 1000x1000 矩阵上运行了 1000 代以上的代码,并获得了 69% 的速度提升。

于 2012-12-12T19:05:13.400 回答