CUDA 5.0内存对齐和合并访问

fah*_*had 2 memory-management cuda

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

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

 The BLOCK_SIZE I use is = 96
 The GRID_DIM I use is = 10
Run Code Online (Sandbox Code Playgroud)

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

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

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

我的理解是:一个线程应该使一个内存访问应该是4个字节,从地址范围,如从0x00到0x80.如果来自warp的线程访问其外部的位置,则其为未加协调的访问.

Jef*_*Sax 9

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

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

只要warp中的所有线程访问同一个块,访问哪个块都无关紧要.

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

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

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

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