为什么Cuda / OpenCL的全球内存中没有银行冲突?

有一点我没想到并且谷歌没有帮助我,为什么可能与共享内存存在冲突,而不是全局内存?与寄存器存在银行冲突吗? UPDATE 哇,我非常感谢Tibbit和Grizzly的两个答案。看来我只能在一个答案上给出绿色复选标记。堆栈溢出我是新手。我想我必须选择一个最好的答案。我可以做点什么来说谢谢答案我不给绿色支票吗?     
已邀请:
简答:全局存储器或寄存器中没有存储体冲突。 说明: 理解原因的关键是掌握操作的粒度。单个线程不访问全局内存。全局内存访问是“合并”的。由于全局内存太慢,因此块内线程的任何访问都被组合在一起,以尽可能少地向全局内存发出请求。 共享内存可以由线程同时访问。当两个线程试图访问同一个银行内的地址时,这会导致银行冲突。 除了分配寄存器之外的任何线程都不能访问寄存器。由于您无法读取或写入我的寄存器,因此您无法阻止我访问它们 - 因此,没有任何银行冲突。 谁可以阅读&写入全球记忆?
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.
因此,一次只有一个线程正在访问它。     
在给定类型的存储器上是否存在存储体冲突显然取决于存储器的结构并因此取决于其目的。 那么为什么共享内存的设计方式会导致银行冲突呢? 这是相对简单的,它不容易设计一个内存控制器,可以同时处理对同一内存的独立访问(事实证明大多数不能)。因此,为了允许半衰期中的每个线程访问单个寻址的字,存储器被存储,每个存储体具有独立的控制器(至少这是如何考虑它,不确定实际的硬件)。这些存储体是交错的,以使顺序线程快速访问顺序存储器。因此,这些银行中的每一个都可以一次处理一个请求,理想情况下允许在半衰期中同时执行所有请求(显然,由于这些银行的独立性,这种模型理论上可以维持更高的带宽,这也是一个优点)。 寄存器怎么样? 寄存器设计为作为ALU指令的操作数访问,这意味着必须以非常低的延迟访问它们。因此,它们可以获得更多的晶体管/位。我不确定在现代处理器中如何访问寄存器(不是那种经常需要的信息,而不是那么容易找到)。然而,在银行中组织寄存器显然是非常不切实际的(对于更简单的架构,您通常会看到所有寄存器挂在一个大型多路复用器上)。所以不,寄存器不存在银行冲突。 全球记忆 首先,全局内存在不同的粒度上工作,然后共享内存。内存以32,64或128字节块访问(对于GT200至少,对于fermi,它总是128B,但是缓存,AMD有点不同),每次你想要块中的东西时,访问/传输整个块。这就是为什么你需要合并访问,因为如果每个线程从不同的块访问内存,你必须传输所有块。 但谁说没有银行冲突?我对此并不完全确定,因为我没有找到任何支持NVIDIA硬件的实际来源,但这似乎是合乎逻辑的: 全局存储器通常分布在几个ram芯片上(可以通过查看图形卡轻松验证)。如果这些芯片中的每一个都像本地存储器一样,那么这将是有意义的,因此如果在同一个存储体上同时存在多个请求,则会发生存储体冲突。然而,对于一件事情来说效果会明显不那么明显(因为内存访问所消耗的大部分时间都是从A到B反复获取数据的延迟),并且它不会是一个工作组“内部”无法理解的效果。 (因为一次只执行一次半衰期,如果半衰期发出多一个请求,你有一个未被解析的内存访问,所以你已经受到了打击,很难衡量这种冲突的影响。所以你只会遇到冲突,如果几个工作组试图访问同一个银行。在gpgpu的典型情况下,你有一个大数据集位于顺序存储器中,所以效果不应该是真的很明显,因为有足够的其他工作组同时访问其他银行,但它应该有可能构建数据集仅集中在几个银行上的情况,这会对带宽产生影响(因为最大带宽来自于所有银行的均等分配访问,因此每个银行都会只有一小部分带宽)。我再也没有读过任何东西来证明nvidia硬件的这个理论(大多数都集中在合并上,当然这更重要,因为它使这成为自然数据集的一个非问题)。然而根据ATI Stream计算指南,这是Radeon卡的情况(对于5xxx:银行相距2kb,你想确保你的所有银行分配你的访问(意味着所有worgroups模拟活跃),所以我可以想象NVidia卡表现相似。 当然对于大多数情况来说,全球记忆中银行冲突的可能性是一个非问题,所以在实践中你可以说: 在访问全局内存时注意合并 访问本地内存时,请注意银行冲突 访问寄存器没问题     
访问同一银行的多个线程并不一定意味着存在银行冲突。如果线程想要从同一个银行内的不同行中同时读取,则存在冲突。     

要回复问题请先登录注册