我一直在阅读CUDA和OpenCL的编程指南,我无法弄清楚银行冲突是什么.他们只是倾向于如何解决问题而不详细说明主题本身.任何人都可以帮我理解吗?如果帮助是在CUDA/OpenCL的背景下,或者只是计算机科学中的银行冲突,我没有偏好.
有一点我没想到并且谷歌没有帮助我,为什么可能与共享内存存在冲突,而不是全局内存?与寄存器存在银行冲突吗?
更新 哇我非常感谢Tibbit和Grizzly的两个答案.看来我只能在一个答案上给出绿色复选标记.堆栈溢出我是新手.我想我必须选择一个最好的答案.我可以做点什么来说谢谢答案我不给绿色支票吗?
我想了解银行冲突是如何发生的.
如果我在全局内存中有一个256大小的数组,并且我在一个Block中有256个线程,我想将该数组复制到共享内存.因此每个线程复制一个元素.
shared_a[threadIdx.x]=global_a[threadIdx.x]
Run Code Online (Sandbox Code Playgroud)
这个简单的行动会导致银行冲突吗?
现在假设数组的大小大于线程数,所以我现在用它来将全局内存复制到共享内存:
tid = threadIdx.x;
for(int i=0;tid+i<N;i+=blockDim.x)
shared_a[tid+i]=global_a[tid+i];
Run Code Online (Sandbox Code Playgroud)
以上代码会导致银行冲突吗?
这篇博客文章解释了内存库冲突如何破坏转置函数的性能.
现在我不禁要问:在"普通"cpu(在多线程上下文中)是否会发生同样的情况?或者这是特定于CUDA/OpenCL?或者它甚至没有出现在现代CPU中,因为它们的缓存大小相对较大?
内核参数存储在片上共享存储器中.如果线程试图访问同一个银行,则共享内存可能存在银行冲突. 所以我的问题是:这是否意味着使用内核参数线程会导致银行冲突?
我刚学会了(为什么只有一个warp由cuda中的SM执行?)Kepler GPU实际上可以同时执行几个(显然是4个)warp的指令.
共享内存库是否也可以同时提供四个请求?如果不是这样,那就意味着银行冲突可能发生在碰巧同时执行的不同warp的线程之间,即使在任何单个warp中没有银行冲突,对吧?有没有关于此的信息?
使用cuda编程时,合并与银行冲突有什么区别?
只是在共享内存中的银行冲突时,全局内存中是否会发生合并?
如果我支持> 1.2支持GPU,我应该担心合并吗?它自己处理合并吗?
共享内存被"条带化"到银行中.正如众所周知的那样,这导致了银行冲突的整个问题.
问题: 但是如何确定共享内存中存在多少个银行("条带")?
(围绕NVIDIA"devtalk"论坛,似乎每块共享内存被"条带化"到16家银行.但我们怎么知道呢?线程暗示这已经有几年了.有没有改变?它是否已修复所有支持 NVIDIA CUDA的卡?有没有办法从运行时API中确定这一点(我没有在那里看到它,例如在cudaDeviceProp下)?是否有一种手动方式在运行时确定它?)
根据我在CUDA文档中的描述,共享内存库冲突与sm_20及更高版本无关,因为在同时请求时会广播值,从而防止出现任何类型的序列化延迟.
文件:
共享存储器硬件在计算能力2.x的设备上得到改进,以支持多个广播字,并且为每个线程的8位,16位,64位或128位的访问产生更少的存储体冲突(G部分). 4.3).
有人可以证实我的断言吗?
我想确保我正确理解共享内存中的库冲突。
我有32段数据。
这些段分别由 128 个整数组成。
[[0, 1, ..., 126, 127], [128, 129, ..., 255], ..., [3968, 3969, ..., 4095]]
Run Code Online (Sandbox Code Playgroud)
warp 中的每个线程仅访问其自己的部分。
线程 0 访问对应于索引 0 的部分 0 的位置 0。
线程 1 访问部分 1 上对应于索引 128 的位置 0。
...
线程 31 访问对应于索引 3968 的部分 31 的位置 0。
这是否意味着我有32倍的银行冲突?
如果是,那么如果我向每个段添加一个填充元素(即总共 129 个元素),那么每个线程将访问一个唯一的存储体。我对吗?