18

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

更新 哇,我真的很感谢 Tibbit 和 Grizzly 的两个答案。看来我只能给一个答案打一个绿色的复选标记。我对堆栈溢出很陌生。我想我必须选择一个答案作为最佳答案。我可以做些什么来感谢我不给绿色检查的答案吗?

4

3 回答 3

36

简短的回答: 在全局内存或寄存器中都没有银行冲突。

解释:

理解为什么的关键是把握操作的粒度。单个线程不访问全局内存。全局内存访问是“合并的”。由于全局内存非常慢,因此块内线程的任何访问都被组合在一起,以尽可能少地对全局内存发出请求。

线程可以同时访问共享内存。当两个线程试图访问同一个 bank 中的地址时,这会导致 bank 冲突。

除了分配给它的线程之外,任何线程都不能访问寄存器。由于您无法读取或写入我的寄存器,因此您无法阻止我访问它们——因此,没有任何银行冲突。

谁可以读写全局内存?

Only blocks. 单个线程可以进行访问,但事务将在块级别处理(实际上是warp / half warp级别,但我尽量不要复杂)。如果两个块访问同一个内存,我不相信它会花费更长的时间,并且它可能会被最新设备中的 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. 因此,一次只有一个线程在访问它。

于 2010-10-02T19:52:47.970 回答
22

给定类型的内存是否存在存储库冲突显然取决于内存的结构,因此也取决于其用途。

那么为什么共享内存的设计方式允许银行冲突呢?

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

寄存器呢?

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

全局内存

首先,全局内存在不同的粒度上工作,然后是共享内存。内存以 32、64 或 128 字节的块访问(至少对于 GT200,对于 fermi,它始终是 128B,但缓存,AMD 有点不同),每次你想要从一个块中获取一些东西时,整个块都会被访问/传输。这就是您需要合并访问的原因,因为如果每个线程都从不同的块访问内存,则您必须传输所有块。

但谁说没有银行冲突?我对此并不完全确定,因为我还没有找到任何实际的资源来支持 NVIDIA 硬件,但这似乎是合乎逻辑的:全局内存通常分布在几个 ram 芯片上(可以通过查看显卡)。这是有道理的,如果这些芯片中的每一个都像一个本地内存库,那么如果在同一个库上同时有多个请求,您就会遇到库冲突。然而,对于一件事,效果会不那么明显(因为内存访问所消耗的大部分时间都是从 A 到 B 获取数据的延迟),而且它不会是“内部”的明显影响 没有阅读任何内容来证明 nvidia 硬件的这一理论(大部分内容都集中在合并上,这当然更重要,因为它使自然数据集成为一个不成问题的问题)。然而,根据 ATI 流计算指南,这是 Radeon 卡的情况(对于 5xxx:银行相隔 2kb,并且您要确保将访问(意味着来自所有模拟活动的工作组)平等地分配到所有银行),所以我会想象 NVidia 卡的行为相似。

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

  • 访问全局内存时注意合并
  • 访问本地内存时注意银行冲突
  • 访问寄存器没有问题
于 2010-10-02T21:52:13.150 回答
4

多个线程访问同一个银行并不一定意味着存在银行冲突。如果线程要同时从同一个 bank 中的 A DIFFERENT ROW 读取,则会发生冲突。

于 2011-02-13T15:55:29.753 回答