bank conflict

 

 

https://www.cnblogs.com/zhcnfyy/p/15184405.html

 

 

bank conflict

参考

对不同bank的访问可同时进行 :为了获得较高的内存带宽,共享存储器被划分为多个大小相等的存储器模块,称为bank,可以被同时访问。因此任何跨越b个不同bank的n个地址的读写操作可以被同时进行,这样就大大提高了整体带宽 ——可达到单独一个bank带宽的b倍。

同一warp中的所有线程访问同一bank可同时进行(广播) : 然而,如果多个线程请求的地址映射到相同的内存bank,那么访问就会被顺序执行。硬件会把冲突的内存请求分为尽可能多的单独的没有冲突的请求,这样就会减少一定的带宽,减少的因子与冲突的内存请求个数相等。当然,也有例外的情况:当一个warp中的所有线程访问同一个共享内存地址时,就会产生一次广播。计算能力为2.0及以上的设备还可以多次广播共享内存访问,这意味着一个warp中任意数量的线程对于同一位置的多次访问也可以同时进行。

为了尽量减少bank冲突,理解共享内存地址如何映射到bank是非常重要的。计算能力5.0的设备,共享内存的bank是这样组织的:连续的32-bits字被分配到连续的bank中,每个bank的带宽是每个时钟周期32bits。;对于计算能力3.0的设备,每个bank的带宽是每个时钟周期64bits;对于计算能力2.0的设备每个bank的带宽是每两个时钟周期32bits

注释:

  • 对于计算能力1.x的设备,warp的大小是32而bank的数量是16。一个warp中线程对共享内存的请求被划分为两次请求:一个请求是前半个warp的另一个请求时后半个warp的。注意如果每个bank中只有一个内存地址是被半个warp中的线程访问的话,是不会有bank冲突的。
  • 对于计算能力为2.x的设备,warp的大小是32而bank的数量也是32。一个warp中线程对共享内存的请求不会像计算能力1.x的设备那样被划分开,这就意味着同一个warp中的前半个warp中的线程与后半个warp中的线程会有可能产生bank冲突的。
  • 计算能力为3.x的设备的bank大小是可以配置的,我们可以通过函数cudaDeviceSetSharedMemConfig()来设置,要么设置为4字节(默认为cudaSharedMemBankSizeFourByte),要么设置为8字节(cudaSharedMemBankSizeEightByte)。当访问双精度的数据时,将bank大小设置为8字节可以帮助避免bank冲突。

当一个warp中的不同线程访问一个bank中的不同的字地址时,就会发生bank冲突。

如果没有bank冲突的话,共享内存的访存速度将会非常的快,大约比全局内存的访问延迟低100多倍,但是速度没有寄存器快。然而,如果在使用共享内存时发生了bank冲突的话,性能将会降低很多很多。在最坏的情况下,即一个warp中的所有线程访问了相同bank的32个不同字地址的话,那么这32个访问操作将会全部被序列化,大大降低了内存带宽。

注意:不同warp中的线程之间不存在什么bank冲突。

 

posted @ 2022-10-12 15:02  sinferwu  阅读(324)  评论(0编辑  收藏  举报