2

我有一个 10 行 96 列的 2D 主机阵列。我将此数组线性加载到我的 cuda 设备全局内存中,即 row1、row2、row3 ... row10。

该数组是浮点类型。在我的内核中,每个线程都从设备全局内存中访问一个浮点值。

 The BLOCK_SIZE I use is = 96
 The GRID_DIM I use is = 10

现在我从合并访问的“Cuda C 编程指南”中了解到,我使用的模式是正确的,通过 warp 连续访问内存位置。但是有一个关于内存 128 字节内存对齐的条款。我无法理解。

Q1) 128字节内存对齐;这是否意味着warp中的每个线程都应该访问从地址0x00(例如)到0x80的4个字节?

Q2) 那么在这种情况下,我是否会进行未合并的访问?

我的理解是:一个线程应该进行一次内存访问,应该是 4 个字节,从地址范围,例如从 0x00 到 0x80。如果来自 warp 的线程访问其外部的位置,则它是未合并的访问。

4

1 回答 1

9

从全局内存加载通常以 128 字节的块完成,在 128 字节边界上对齐。合并内存访问意味着您将所有访问从您的 warp 保留到一个 128 字节的块。(在旧卡中,内存必须按线程 ID 的顺序访问,但新卡不再有此要求。)

如果你的 warp 中的 32 个线程每个读取一个浮点数,你将从全局内存中读取总共 128 个字节。如果内存对齐正确,所有读取都来自同一个块。如果对齐关闭,您将需要两次读取。如果您执行类似的操作a[32*i],那么每次访问都将来自全局内存中不同的 128 字节块,这将非常慢。

只要一个warp中的所有线程都访问同一个块,您访问哪个块并不重要。

如果您有一个包含 96 个浮点数的数组,那么如果i您的 warp 中具有索引的每个线程都访问a[i],这将是一个合并读取。与a[i+32]or相同a[i+64]

因此,Q1 的答案是所有线程都需要保持在长度为 128 字节的同一块内,该块在 128 字节边界上对齐。

Q2 的答案是,如果您的数组正确对齐,并且您的访问是a[32*x+i]具有i线程 ID 和x所有线程相同的任何整数的形式,您的访问将被合并。

根据编程指南的第 5.3.2.1.1 节,内存始终在至少 256 字节边界上对齐,因此创建的数组cudaMalloc始终正确对齐。

于 2013-05-30T23:04:45.050 回答