什么是银行冲突? (做Cuda / OpenCL编程)

我一直在阅读CUDA和OpenCL的编程指南,我无法弄清楚银行冲突是什么。 他们只是潜心钻研如何解决问题,而没有详细阐述这个问题。 有人能帮我理解吗? 如果帮助是在CUDA / OpenCL的环境下,或者只是在计算机科学中的银行冲突,我没有任何偏好。

对于NVIDIA(和amd)gpus的本地内存分为内存条。 每个银行一次只能访问一个数据集,所以如果一个半变换尝试从/向同一个银行加载/存储数据,访问必须被序列化(这是银行冲突)。 对于gt200 gpus,有16个银行(32个银行为费米),16或32个银行为AMD gpus(57xx或更高:32,一切低于16)),这是交织在32位的颗粒(所以字节0-3是在银行1,银行4-7,银行1,银行64-69等)。 为了更好的可视化,它基本上是这样的:

Bank | 1 | 2 | 3 |... Address | 0 1 2 3 | 4 5 6 7 | 8 9 10 11 |... Address | 64 65 66 67 | 68 69 70 71 | 72 73 74 75 |... ... 

所以,如果每个线程在一个半warp访问连续32位值没有银行冲突。 这个规则的一个例外(每个线程都必须访问自己的存储区)是广播的:如果所有的线程都访问同一个地址,那么这个值只能被读取一次并被广播到所有的线程上(对于GT200来说,它必须是半转换中的所有线程,相同的地址,iirc fermi和AMD gpus可以为任何数量的线程访问相同的值)。

可以并行访问的共享内存分为模块(也称为库)。 如果两个内存位置(地址)出现在同一个存储区中,则会发生银行冲突,在此期间访问将被串行完成,从而丧失了并行访问的优势。

简而言之,当存储器访问模式不能在存储器系统中可用的存储体中分配IO时,银行冲突就是一种情况。 下面的例子阐述了这个概念:

让我们假设我们有二维512×512整数arrays,而我们的DRAM或存储器系统有512个存储体。 默认情况下,arrays数据将以arr [0] [0]进入存储区0,arr [0] [1]存入存储区1,arr [0] [2]存储到存储区2的方式进行布局…. arr [0] [511]转到511银行。推广arr [x] [y]占用银行编号y。 现在一些代码(如下所示)开始以列主要方式访问数据,即。 在保持y不变的情况下改变x,那么最终的结果将是所有连续的存储器访问将会碰到同一个银行 – 因此存在银行冲突。

 int arr[512][512]; for ( j = 0; j < 512; j++ ) // outer loop for ( i = 0; i < 512; i++ ) // inner loop arr[i][j] = 2 * arr[i][j]; // column major processing 

编译器通过缓冲数组或使用素数的素数来避免这样的问题。

(CUDA银行冲突)我希望这将有助于..这是非常好的解释…

http://www.youtube.com/watch?v=CZgM3DEBplE

http://en.wikipedia.org/wiki/Memory_bank
http://mprc.pku.cn/mentors/training/ISCAreading/1989/p380-weiss/p380-weiss.pdf

从这个页面,你可以find关于内存银行的细节。 但与@Grizzly所说的有点不同。 在这个页面上,银行是这样的

银行1 2 3

地址| 0,3,6 … | | 1,4,7 … | | 2,5,8 … |

希望这会有所帮助

Interesting Posts