共享内存库与char数组冲突

时间:2016-02-11 00:46:52

标签: cuda gpgpu

我理解处理4字节数据类型时的银行冲突,但我想知道 如果我们使用以下代码获得任何银行冲突(4路/ 8路?)

__shared__ char shared[];
foo = shared[threadIdx.x];

上面的代码导致warp中的4个连续线程访问同一个bank中的相同字地址。

类似的内存访问模式会导致任何cuda设备系列的银行冲突吗?显然,它仅适用于旧卡,但我想确认。

我的问题可以进一步推广,如果多个线程访问相同的存储区可寻址单元[8字节或4字节]但每个都需要一小部分。硬件是否会处理此类请求而不存在任何银行冲突?谢谢

1 个答案:

答案 0 :(得分:2)

所有cc2.0和更新的GPU设备都有一个广播机制,以便参与warp请求的任意数量的线程访问给定的32位对齐位置或该位置的任何部分(或多组此类线程) ,每个组访问给定的32位对齐位置或该位置的任何部分),该组中的线程将在单个事务中进行服务,而不进行序列化。

来自the documentation

  

warp的共享内存请求不会在访问同一个32位字内任何地址的两个线程之间产生存储体冲突(即使这两个地址属于同一个存储区):在这种情况下,对于读取访问,该字被广播到请求线程(多个字可以在单个事务中广播),对于写访问,每个地址只由其中一个线程写入(该线程执行写操作未定义)。

对于支持8字节组模式且处于8字节组模式的设备,上述广播机制推广到64位对齐位置。

请注意,我已经仔细选择了我的措辞。假设我在一个warp请求中有两个这样的广播组。现在还假设这些组正在寻址两个不同的位置,但同一个银行中有两个位置。例如。组A的目标地址为0,组B的目标地址为1024.在这种情况下,参与组A的所有线程将在单个事务中进行服务,参与组B的所有线程将在单个事务中进行服务,但那些两组将相互序列化。

另一方面,如果组目标地址0和组B目标地址8,则它们位于不同的组中,因此组A中的所有线程组B中的所有线程都可以在单个交易中提供服务,因为每个请求允许多个广播。