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

问题描述 投票:0回答:5

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

multithreading cuda opencl nvidia bank-conflict
5个回答
133
投票

对于 nvidia(以及 amd)GPU,本地内存被分为多个内存库。每个存储体一次只能寻址一个数据集,因此如果 halfwarp 尝试从同一存储体加载/存储数据,则必须对访问进行序列化(这是存储体冲突)。对于 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 可以对任意数量的访问线程执行此操作相同的值)。


19
投票

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


16
投票

假设我们有二维 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。现在一些代码(如下所示)开始以列主要方式访问数据,即。改变 x 同时保持 y 不变,那么最终结果将是所有连续的内存访问都将到达同一个存储体 - 因此,存储体冲突。

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

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


12
投票

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


2
投票
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...|

希望这会有所帮助

© www.soinside.com 2019 - 2024. All rights reserved.