每个warp线程从共享内存加载一个相同的32个字节(ulong4)

时间:2012-09-26 18:43:01

标签: cuda gpu gpgpu nvidia

如果每个warp访问同一地址的共享内存,那么如何加载32字节的数据(ulong4)?它会'广播'吗?访问时间是否与每个线程加载2个字节的'unsigned short int'相同?

现在,如果我需要在每个warp中从共享内存32/64加载相同的字节,我该怎么办呢?

1 个答案:

答案 0 :(得分:1)

在计算能力之前的设备上3.0共享内存访问总是32位/ 4字节宽,并且如果warp的所有线程访问相同的地址,则将广播。更广泛的访问将编译为多个指令。

在计算能力3.0上,可以使用cudaDeviceSetSharedMemConfig()将共享内存访问配置为32位宽或64位宽。所选设置将适用于整个内核。


[因为我最初错过了问题中的“共享”这个小词,我给出了一个完全偏离主题的全局记忆答案。既然那个应该仍然是正确的,我会留在这里:]

取决于:

  • 计算能力1.0和1.1不广播并使用64个单独的32字节内存事务(两次16字节,扩展到每个线程的最小32字节事务大小)
  • 计算能力1.2和1.3广播,因此两个32字节事务(两次16字节,扩展到最小32字节事务大小)足以满足warp的所有线程
  • 计算能力2.0及更高版本只需读取128字节高速缓存行并满足所有请求。

计算能力1.x设备将浪费50%的传输数据,因为单个线程最多可以加载16个字节,但最小事务大小为32个字节。另外,32字节事务比128字节事务慢得多。

由于最小事务大小,每个线程只读取8个字节的时间相同,并且因为数据路径足够宽,可以为每个事务传输8个或16个字节到每个线程。

读取2×或4×数据将在计算能力1.x上花费2倍或4倍,但如果数据落入相同的高速缓存行,则仅在2.0及更高版本上仅更长时间,因此没有进一步的内存事务是必要的。

因此,在计算能力2.0及更高版本上,您无需担心。在1.x上通过常量缓存或纹理读取数据(如果它是常量),或者在共享内存中重新排序(假设你的内核是内存带宽限制的)。