cway内核为康威的生命游戏

时间:2010-12-14 10:42:40

标签: cuda parallel-processing conways-game-of-life

我正在尝试计算在一系列Conway的GOL中为n次迭代的pxq矩阵进行的转换次数。例如,给定1次迭代,初始状态为1闪烁(如下所示)。将有5个过渡(2个出生,1个存活,2个来自人口不足的死亡)。我已经有了这个工作,但我想将这个逻辑转换为使用CUDA运行。以下是我想要移植到CUDA的内容。

alt text     代码:

    static void gol() // call this iterations x's
    {
        int[] tempGrid = new int[rows * cols]; // grid holds init conditions
        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                tempGrid[i * cols + j] = grid[i * cols + j];
            }
        }

        for (int i = 0; i < rows; i++)
        {
            for (int j = 0; j < cols; j++)
            {
                int numNeighbors = neighbors(i, j); // finds # of neighbors

                if (grid[i * cols + j] == 1 && numNeighbors > 3)
                {
                    tempGrid[i * cols + j] = 0;
                    overcrowding++;
                }
                else if (grid[i * cols + j] == 1 && numNeighbors < 2)
                {
                    tempGrid[i * cols + j] = 0;
                    underpopulation++;
                }
                else if (grid[i * cols + j] == 1 && numNeighbors > 1)
                {
                    tempGrid[i * cols + j] = 1;
                    survival++;
                }
                else if (grid[i * cols + j] == 0 && numNeighbors == 3)
                {
                    tempGrid[i * cols + j] = 1;
                    birth++;
                }
            }
        }

        grid = tempGrid;
    }

2 个答案:

答案 0 :(得分:3)

您的主要减速将成为主内存访问。因此,我建议您根据可用的硬件选择较大的线程块大小。 256(16x16)是跨硬件兼容性的不错选择。这些线程块中的每一个都将计算板的略小部分的结果 - 如果您使用16x16,它们将计算板的14x14部分的结果,因为存在单个元素边界。 (使用16x16块来计算14x14块而不是16x16块的原因是用于内存读取合并。)

将董事会划分为(例如)14x14块;那就是你的网格(无论你认为合适,都有条理,但最有可能是board_width / 14board_height / 14

在内核中,让每个线程将其元素加载到共享内存中。然后syncthreads。然后让中间的14x14元素计算新值(使用存储在共享内存中的值)并将其写回全局内存。共享内存的使用有助于最小化全局读取和写入。这也是让你的线程块大小尽可能大的原因 - 边缘和角落是“浪费”全局内存访问,因为在那里获取的值只能使用1或3次,而不是9次。

答案 1 :(得分:0)

以下是您可以采取的一种方式:

  1. 每个线程对网格的1个元素进行计算
  2. 每个线程首先将一个元素从主网格加载到共享内存
  3. 螺纹块边缘的螺纹也需要加载边界元素
  4. 然后,每个线程可以根据共享内存的内容进行生存计算
  5. 然后每个线程将其结果写回主存储器