【发布时间】:2022-01-20 19:18:41
【问题描述】:
我对银行冲突有点困惑,使用内存填充和合并内存访问来避免它们。到目前为止我读过的内容:从全局内存中合并内存访问是最佳的。如果无法实现,则可以使用共享内存对当前块所需的数据进行重新排序,从而使合并访问成为可能。但是,当使用共享内存时,必须注意银行冲突。避免存储库冲突的一种策略是将存储在共享内存中的数组填充 1。考虑 this blog post 中的示例,其中 16x16 矩阵的每一行都填充 1,使其成为共享内存中的 16x17 矩阵。
现在我明白了使用内存填充可能会避免银行冲突,但这是否也意味着内存不再对齐?例如。如果我将全局内存移动 1 从而使其未对齐,则一个扭曲将需要访问两个内存通道而不是一个,因为最后一个数字与所有其他数字不在同一通道中。因此,据我了解,合并内存访问和内存填充是相互矛盾的概念,不是吗?非常感谢一些澄清!
【问题讨论】:
-
对全局内存的非合并访问非常昂贵。在共享内存中,与银行冲突相比,这不是问题(如果有的话)。
-
@PaulG。谢谢你的评论。你有这方面的参考吗?例如。它是由 nvidia 官方声明还是有某种研究?
-
This 专门用于 Ampere,但旧架构的文档也是如此。在全局内存的上下文中明确提到了合并。其他提及不那么明确,但我没有找到(快速搜索)任何明确提及共享内存的内容。
-
顺便说一句,您还可以使用 warp shuffle 指令更正数据布局(这也是由共享内存单元完成的,只是没有实际存储数据)。您将以合并的方式读取数据(可能不止一条记录),然后根据实际需要在线程之间重新洗牌。存储的相反方式。
-
您可以使用 Nsight Compute 获得有关您的代码的明确答案。对于共享内存,只有使用的通道数很重要,因此访问同一个元素(而不仅仅是同一个通道中的几个元素)只计算一次。因此,对齐(int/float 的 4 个字节除外)和访问内存地址的连续性都不是共享内存的问题。
标签: cuda memory-access bank-conflict