【问题标题】:cuda kernel for conway's game of life康威生命游戏的 cuda 内核
【发布时间】:2010-12-14 10:42:40
【问题描述】:

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

代码:

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

【问题讨论】:

  • 您具体需要什么帮助 - 如何并行化、存储、实际 CUDA 编程等方面的想法?
  • 对不起,我应该如何处理并行性?

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


【解决方案1】:

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

将棋盘分成(比如说)14x14 的块;那是你的网格(按照你认为合适的方式组织,但很可能是board_width / 14board_height / 14

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

【讨论】:

    【解决方案2】:

    这是您可以继续的一种方法:

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

    【讨论】:

      猜你喜欢
      • 2013-02-21
      • 1970-01-01
      • 2010-09-07
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多