CUDA之thread访问总结

问:对于结构体数组 typedef struct{float x; float y; float z;}  float3;  float3 d=data[id], id为线程索引号,则对于一个

wrap,为其中的每个线程读取4字节需要几次访存呢?为其中的每一个线程读取12字节需要几次访存呢?

答:如果只是为warp中的每个线程读1个该结构体的实例的一个分量(4B)的话。那么如果所有线程在都访问的不是同一个实例的情况下,最好的情况下,将只为每个线程读取4B. 每个线程只生成1条访存指令。但是这是所谓的requested读取的大小,实际上,L2和显存控制器都会将读取放大的。例如假设你现在的访问模型是warp中的每个线程都读取连续的一个该实例的一个分量,因为我们的显存不是真的随机的,它有最小的传输粒度大小。你这样每12B只要4B的话,实际上将有约3倍的读取放大的。一个warp将至少需要12次L2传输的(384B)。你可以用profiler报告的global memory实际读取速率,和请求的读取速率,观察到大约前者实际是后者的3倍的大小。


关于第二个问题,因为N卡的硬件目前不支持96-bit读取,如果你这结构体就这样写的话,无任何对齐上的暗示。那么每个线程的对1个实例的访问,只能被拆分成3条4B读取的。(N卡目前支持64-bit和128-bit读取的,但木有96-bit。这样再无对其性的暗示的话,将只能拆分成3 * 32-bit。而不能1x64-bit + 1x32-bit)。


感谢来访。

PS: 请按照提示观察profiler报告的只读取一个分量时候的读取放大效果(或者说,降低等效访存能力到到1/3的效果)。


PS: 有内置的float3的,无需手工重新定义

问:那么如果所有线程在都访问的不是同一个实例的情况下,最好的情况下,将只为每个线程读取4B. 每个线程只生成1条访存指令。这句话没理解

答:如果1个warp只访问同一个float3的同一个分量的话,这实际上结果可以被广播到所有线程中的。只进行一次L2传输的(不考虑DRAM)。但如果访问的是同时不同的float3的

一个分量,则如同上文所说,L2将多次完成对warp的传输请求。


问:这个12次L2中的12次是不是通过如下方式计算:一个线程访问12字节,所以一个wrap就需要访问32*12=384字节,而一次访问的最小传输粒度是32字节,故382除以32等

于12次L2是吗?

答:嗯嗯。是这样计算的。但这只是一般情况,可能L2会导致更多的传输的(例如在有L1参与的情况下)。你可以参考手册上关于如何bypass掉L1的内容。(不同计算能力的

卡略有区别),L1采用的是128B的cache line的,可能会导致L2传输更多。(如果你认为这样对性能有利的话)。

问:那么每个线程的对1个实例的访问,只能被拆分成3条4B读取的。这句话也就是说如果一个线程要访问结构体数组中对应的一个元素float3 d(12字

节 d.x  d.y   d.z),是需要分三次访问的,一次访问d.x  一次d.y  一次d.z 共三次是吧?

答:嗯嗯。是的。这种情况下的 global memory读取,编译器将会生成三条4B读取指令。

问:虽然第一次访问d.x 时,L2的缓存是32B,32B缓存中可能已经包含有dy,dz;但是仍然需要第二次访问d.y,第三次d.z是吧?

答:往往会直接从cache中传过来。指令是必须要有的。但数据的来源是另外一回事。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值