CUDA执行模型的特征之一指令都是以线程束为单位进行发布和执行,存储操作也是如此。
通常情况下,如图所示,全局内存是通过缓存进行加载,而加载请求是通过所谓“内存事务”来实现的,“内存事务”分为32字节和128字节两种。要么一次性加载32字节,要么一次性加载128字节,这主要取决于设备的缓存路径。
如果对全局内存的访问使用L1/L2缓存存储(路径1),那么访问必须由128字节的“内存事务”完成,因此一行L1的缓存的大小是128字节。
如果对全局内存的访问仅使用L2缓存存储(路径2),那么访问则由32字节的“内存事务”完成,因此一行L1的缓存的大小是32字节。
对齐访问:
对齐访问含义就是如果”内存事务“(32和128字节两种)的访问首地址是缓存粒度(L1的128字节或L2缓存的32字节)的偶数倍,即实现了对齐访问。
合并访问:
在L1缓存的情况下,由”128字节内存事务“完成访问,如果恰好一个线程束访问的地址是连续的128字节,且首地址恰好又是128的倍数。那么这种访问就说所谓合并访问。
如图分别是对齐和非对齐合并访问的示意图,由于对齐且连续访问128字节,出现了合并访问。
内存优化的目标在于,通过更少的”内存事务“获得更多的内存请求,因此需要尽量进行对齐合并访问。
注意:在Fermi架构的机器上,L1缓存是默认参与对全局的加载。后面的架构默认是不启用L1缓存的,如果要使用,使用编译指令:-Xptxas -dlcm=ca. 禁用则使用-Xptxas -dlcm=cg