CUDA 5.0内存对齐和合并访问



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

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

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

现在我从合并访问的"Cuda C编程指南"中了解到,我使用的模式是正确的,通过warp连续访问内存位置。但是有一个关于内存128字节内存对齐的子句。我不明白。

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

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

我的理解是:一个线程应该使一个内存访问应该是4字节,从地址范围,如从0x00到0x80。

从全局内存加载通常以128字节的块为单位,按128字节的边界对齐。合并内存访问意味着将所有访问保存在一个128字节的块上。(在旧卡中,必须按照线程id的顺序访问内存,但是新卡不再有这个要求。)

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

无论你访问哪个块,只要在一个warp中的所有线程访问同一个块。

如果你有一个96个浮点数的数组,那么如果每个线程索引i在你的warp访问a[i],它将是一个合并读取。与a[i+32]a[i+64]相同。

所以,第1题的答案是所有线程都需要保持在长度为128字节的相同块内,以128字节的边界对齐。

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

根据编程指南的第5.3.2.1.1节,内存总是以至少256字节的边界对齐,所以用cudaMalloc创建的数组总是正确对齐。

最新更新