我还没有弄清楚并且谷歌没有帮助我的一件事是,为什么有可能与共享内存发生银行冲突,但在全局内存中却没有?银行与寄存器会存在冲突吗?

更新哇,我真的很感谢 Tibbit 和 Grizzly 的两个回答。看来我只能给一个答案打绿色复选标记。我对堆栈溢出很陌生。我想我必须选择一个答案作为最佳答案。我可以对我没有打绿勾的答案说声谢谢吗?

有帮助吗?

解决方案

<强>短答案:有在任一全局存储器或寄存器中没有组冲突

<强>解释

要理解的关键原因是把握操作的粒度。单个线程不访问全局内存。全球存储器访问被“合并”。由于全局存储器是洙慢,一个块内由线程的任何访问被分组在一起,以使尽可能少的请求到全局存储器成为可能。

共享存储器可以由线程同时进行访问。当两个线程试图在同一组内访问的地址,这将导致一个存储体冲突。

寄存器不能被任何线程除了其所分配的一个进行访问。既然你不能读或写我的寄存器,你不能访问他们阻止了我 - 因此,目前还没有任何银行冲突

谁可以读取和写入全局内存?

Only blocks。单个线程可以访问,但该交易将在块级进行处理(实际上经线/半弯曲的水平,但我想太复杂)。如果两个块访问相同的内存,我不相信它会需要更长的时间,并有可能发生在最新的设备L1高速缓存加速 - 尽管这不是透明明显

参与可以读和写到共享存储器吗

Any thread within a given block.如果你只有每块1线你不能有一个银行的冲突,但你不会有合理的性能。因为块与几个分配发生冲突的银行,比如512个线程,他们都在争夺同一家银行(不完全一样的地址)内不同的地址。有这些冲突在CUDA C语言编程指南年底的一些优秀的图片 - 图G2,167页(实际页面的PDF 177)上。 链接到版本3.2

参与可以读与写到寄存器吗

Only the specific thread to which it is allocated.因此只有一个线程被一次访问它。

其他提示

给定类型的内存是否可能存在存储体冲突显然取决于内存的结构及其用途。

那么为什么共享内存的设计方式会允许存储体冲突呢?

这相对简单,设计一个可以同时处理对同一内存的独立访问的内存控制器并不容易(事实证明大多数都不能)。因此,为了允许 halfwarp 中的每个线程访问单独寻址的字,内存被存储起来,每个存储体都有一个独立的控制器(至少人们可以这么想,不确定实际的硬件)。这些存储体交错排列,使连续线程能够快速访问连续内存。因此,这些存储体中的每一个都可以一次处理一个请求,理想情况下允许同时执行 halfwarp 中的所有请求(显然,由于这些存储体的独立性,该模型理论上可以维持更高的带宽,这也是一个优点)。

那么寄存器呢?

寄存器被设计为作为 ALU 指令的操作数进行访问,这意味着它们必须以非常低的延迟进行访问。因此,他们获得了更多的晶体管/位来实现这一点。我不确定现代处理器中寄存器的访问方式到底如何(不是您经常需要的信息,也不是那么容易找到的信息)。然而,在存储体中组织寄存器显然是非常不切实际的(对于更简单的架构,您通常会看到所有寄存器都挂在一个大的多路复用器上)。所以不会,寄存器不会出现银行冲突。

全局内存

首先,全局内存的工作粒度与共享内存不同。内存以 32、64 或 128 字节块进行访问(至少对于 GT200,对于 fermi 总是 128B,但缓存,AMD 有点不同),每次您想要从一个块中获取某些内容时,都会访问/传输整个块。这就是为什么需要合并访问,因为如果每个线程都从不同的块访问内存,则必须传输所有块。

但谁说没有银行冲突呢?我对此并不完全确定,因为我还没有找到任何实际来源来支持 NVIDIA 硬件,但这似乎是合乎逻辑的:全局内存通常分布到多个 RAM 芯片(可以通过查看显卡轻松验证)。如果这些芯片中的每一个都像一个本地内存库,那么如果同一个存储体上有多个同时请求,您就会遇到存储体冲突,这是有道理的。然而,对于一件事来说,影响不太明显(因为内存访问消耗的大部分时间都是从 A 到 B 获取数据的延迟),并且在一个工作组“内部”不会产生明显的影响(因为一次只有一个 halfwarp 执行,并且如果该 halfwarp 发出多个请求,则您将拥有未合并的内存访问,因此您已经受到了打击,因此很难衡量这一冲突的影响。因此,只有当多个工作组尝试访问同一银行时,才会发生冲突。在 gpgpu 的典型情况下,您有一个位于顺序内存中的大型数据集,因此影响实际上并不明显,因为有足够多的其他工作组同时访问其他银行,但应该可以构建数据集的情况仅以少数银行为中心,这将对带宽造成影响(因为最大带宽将来自所有银行的平均分配访问,因此每个银行仅拥有该带宽的一小部分)。同样,我还没有阅读任何内容来证明 nvidia 硬件的这一理论(大多数内容都集中在合并上,这当然更重要,因为它使得这对于自然数据集来说不再是问题)。然而,根据 ATI 流计算指南,这是 Radeon 卡的情况(对于 5xxx:银行相距 2kb,并且您希望确保将访问权限(即来自所有工作组的同时活动的)平等地分配给所有银行),因此我认为 NVidia 卡的行为类似。

当然,对于大多数情况,全局内存上银行冲突的可能性不是问题,所以在实践中你可以说:

  • 访问全局内存时注意合并
  • 访问本地内存时注意存储体冲突
  • 访问寄存器没有问题

多个线程访问同一存储体并不一定意味着有一个存储体冲突。还有,如果线程要从不同行的同一银行内同时读取冲突。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top