根据我在 CUDA 文档中读到的内容,共享内存库冲突与 sm_20 及更高版本无关,因为在同时请求值时会广播值,从而防止任何类型的序列化延迟。
文档:
共享内存硬件在计算能力 2.x 的设备上得到了改进,以支持多个广播字,并为每个线程的 8 位、16 位、64 位或 128 位访问产生更少的存储库冲突(第 G.2 节)。 4.3)。
有人可以证实我的说法吗?
根据我在 CUDA 文档中读到的内容,共享内存库冲突与 sm_20 及更高版本无关,因为在同时请求值时会广播值,从而防止任何类型的序列化延迟。
文档:
共享内存硬件在计算能力 2.x 的设备上得到了改进,以支持多个广播字,并为每个线程的 8 位、16 位、64 位或 128 位访问产生更少的存储库冲突(第 G.2 节)。 4.3)。
有人可以证实我的说法吗?
不,它们不是“无关紧要的”。
我相信您的困惑可能是由于对银行冲突的普遍误解,即“银行”在某种程度上等于“位置”。银行和地点之间是有关系的,但不一定是平等的。
举一个简化的例子,假设我们有 4 个银行(让我们将讨论限制在 32 位事务,以及自然对齐的 32 位存储,例如int
或float
)。银行和位置(int
或float
索引“地址”)之间的关系如下:
address: bank:
0 0 <-----------------------Thread 0
1 1
2 2 ------Thread 1
3 3 /
4 0 <---------Thread 2
5 1
6 2
7 3
8 0 <-----------------------Thread 3
...
例如,我们看到地址 1 和 5 在同一个银行中,但它们不在同一个位置。
每当一个 warp 中的两个或多个线程由于特定的 warp 事务(例如从共享内存中读取)而试图访问同一bank中的数据时,就会出现银行冲突(在任何架构上)。
在 pre-fermi 的情况下,即使多个线程从同一个位置(即地址)读取,这也是一个 bank 冲突,因为这些线程正在从同一个 bank 读取。
在 cc2.x 或更高版本中,引入了广播机制。除了一种特殊情况外,这种机制对银行冲突的一般情况没有影响。当多个线程从同一个位置读取时,这不再是银行冲突,所有从该位置读取的线程都将在特定周期内接收数据,无需序列化。
但是,在任何情况下,如果多个线程从同一 bank中的不同位置读取,则在任何当前 GPU 架构下都是 bank 冲突。
在上图中,如果线程 0 从位置/地址 0 读取,线程 3 从位置/地址 8 读取,这将始终是任何当前架构上的存储体冲突(假设这是一个只有 4 个存储体的简化示例)。如果线程 1 和线程 2 都从位置/地址 4 读取,这是 pre-fermi 上的银行冲突,但不是所有 fermi 设备及以后的设备。
对于 32 bank 排列,这是一种实际的 bank 配置,共享内存中任何位置的bank由索引的低 5 位或该位置的偏移量给出,而不管该位置是否恰好属于 aint
或float
数组。