【发布时间】:2011-04-20 00:06:21
【问题描述】:
我一直在阅读 CUDA 和 OpenCL 的编程指南,但我无法弄清楚银行冲突是什么。他们只是深入研究如何解决问题而没有详细说明主题本身。有人可以帮我理解吗?如果帮助是在 CUDA/OpenCL 的上下文中,或者只是计算机科学中一般的银行冲突,我没有偏好。
【问题讨论】:
标签: cuda opencl nvidia bank-conflict
我一直在阅读 CUDA 和 OpenCL 的编程指南,但我无法弄清楚银行冲突是什么。他们只是深入研究如何解决问题而没有详细说明主题本身。有人可以帮我理解吗?如果帮助是在 CUDA/OpenCL 的上下文中,或者只是计算机科学中一般的银行冲突,我没有偏好。
【问题讨论】:
标签: cuda opencl nvidia bank-conflict
对于 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 位值,则不会发生存储库冲突。该规则的一个例外(每个线程必须访问自己的银行)是广播: 如果所有线程都访问同一个地址,则该值只读取一次并广播给所有线程(对于 GT200,它必须是 halfwarp 中的所有线程都访问同一个地址,iirc fermi 和 AMD gpus 可以对任意数量的线程访问执行此操作相同的值)。
【讨论】:
可以并行访问的共享内存被划分为模块(也称为银行)。如果两个内存位置(地址)出现在同一个 bank 中,则会发生 bank 冲突,在此期间访问是串行完成的,失去了并行访问的优势。
【讨论】:
简单来说,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,那么最终结果将是所有连续的内存访问都会命中同一个 bank——因此会发生 bank 冲突。
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://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...|
希望这会有所帮助
【讨论】: