106

我一直在阅读 CUDA 和 OpenCL 的编程指南,但我无法弄清楚银行冲突是什么。他们只是深入研究如何解决问题,而没有详细说明主题本身。有人可以帮我理解吗?如果帮助是在 CUDA/OpenCL 的上下文中,或者只是计算机科学中的一般银行冲突,我没有偏好。

4

5 回答 5

114

对于 nvidia(以及 AMD)gpus,本地内存分为内存库。每个 bank 一次只能寻址一个数据集,因此如果 halfwarp 尝试从同一 bank 加载/存储数据,则必须对访问进行序列化(这是 bank 冲突)。对于 gt200 gpus,有 16 个库(对于 fermi 有 32 个库),对于 AMD gpus 有 16 或 32 个库(57xx 或更高:32,以下所有内容:16)),它们以 32 位的粒度交错(因此字节 0-3 在银行 1、银行 2 中的 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 |...
...

因此,如果 halfwarp 中的每个线程都访问连续的 32 位值,则不会发生存储库冲突。这条规则的一个例外(每个线程必须访问自己的 bank)是广播:如果所有线程访问同一个地址,则该值只读取一次并广播到所有线程(对于 GT200,它必须是半束中的所有线程都访问相同的地址,iirc fermi 和 AMD gpus 可以对访问相同值的任意数量的线程执行此操作)。

于 2010-10-01T19:38:54.080 回答
17

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

于 2010-10-01T18:16:51.790 回答
12

简而言之,bank 冲突是任何内存访问模式未能在内存系统中可用的 bank 之间分配 IO 的情况。以下示例详细说明了该概念:-

假设我们有二维 512x512 整数数组,并且我们的 DRAM 或内存系统中有 512 个存储体。默认情况下,数组数据的布局方式是 arr[0][0] 进入 bank 0,arr[0][1] 进入 bank 1,arr[0][2] 进入 bank 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

编译器通常通过缓冲数组或使用数组中的素数元素来避免此类问题。

于 2012-07-15T11:10:55.547 回答
9

(CUDA银行冲突)我希望这会有所帮助..这是非常好的解释......

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

于 2013-11-16T13:36:02.950 回答
1

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

从此页面中,您可以找到有关存储库的详细信息。但这与@Grizzly 所说的有点不同。在这个页面,银行是这样的

银行 1 2 3

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

希望这会有所帮助

于 2012-11-23T02:31:03.700 回答