从我在CUDA文档中读到的,共享内存库冲突在sm_20和更高级别上是无关的,因为值在同时请求时被广播,防止任何类型的序列化延迟。
文档:
有人能证实我的断言吗?在计算设备上改进了共享内存硬件能力2。X来支持多个广播词并生成对于8位、16位、64位或每线程128位(章节G.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,例如,在同一个银行,但它们不是相同的位置。
Bank冲突(在任何架构上)可能会出现,当一个warp中的两个或多个线程试图访问同一个 Bank 中的数据时,由于一个特定的warp事务(例如从共享内存中读取)。
在fermi之前的情况下,即使多个线程从相同的位置(即地址)读取,这也是一个银行冲突,因为这些线程从同一个银行读取。
在cc2。X或更大的情况下,引入了广播机制。除了一种特殊情况外,该机制对银行冲突的一般情况没有影响。当多个线程从同一位置读取数据时,这不再是银行冲突,所有从该位置读取的线程将在特定周期内接收数据,而不需要序列化。
然而,在任何情况下,如果多个线程从同一bank中的不同位置读取,则在任何当前GPU架构下都是银行冲突。
在上面的图片中,如果线程0从位置/地址0读取,线程3从位置/地址8读取,那么在任何当前架构中总是是一个银行冲突(假设这是一个只有4家银行的简化示例)。如果线程1和线程2都从位置/地址4读取,则在pre-fermi上存在bank冲突,但在所有fermi设备上都没有。对于一个32 bank排列,这是一个实际的bank配置,共享内存中任何位置的bank由该位置的索引或偏移量的后5位给出,无论该位置碰巧属于int
还是float
数组。