不完整的全局内存访问是否合并?

时间:2014-02-21 11:56:06

标签: c++ cuda memory-access coalescing

是否合并,如果n < warpSize

// In kernel
int x;
if (threadId < n)
  x = globalMem[threadId];

如果某些NwarpSize不可分割,则此类情况会在周期的最后一次迭代中出现。我应该运行这些分区并分配设备内存,只能被warpSize整除,否则它会被合并?

1 个答案:

答案 0 :(得分:1)

cuda programming guide - thread hierachy中记录的那样正确计算threadId,则此访问权限将被合并 - threadId = threadIdx.x就是这种情况。

对于不同的计算体系结构,内存合并略有不同。有关详细信息,请访问appendix G of cuda programming guide

一般情况下,如果线程从第一个线程访问的元素的地址开始抓取内存中的连续元素,则可以说全局内存访问是合并的。

假设你有一个浮点数组。
float array[]
并且你的内存访问以这种方式看起来

array[threadIdx.x == 0, threadId.x == 1, threadIdx.x == 2, ..., threadIdx.x == 31]

比您的访问权限更高。

但是如果以这种方式访问​​内存(例如交错)

array[threadIdx.x == 0, NONE, threadId.x == 1, NONE, threadIdx.x == 2, ..., NONE,  threadIdx.x == 31]

比你的访问没有合并(NONE意味着任何线程都不能访问这个数组元素)

在第一种情况下,你可以获得128个连续字节的内存。在第二种情况下,您获取256个字节。对于第二种情况,需要两个warp来从全局内存加载内存而不是第一种情况下的一个warp。但在这两种情况下,以下计算只需要32个浮点元素(即128个字节)。因此,在这种简单的情况下,您的全局负载率将从1.0降至0.5。