为什么一个线程访问两个连续的元素会导致“bank冲突”?

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

bank conflict

如上红框所示,我不明白为什么一个线程连续访问两个数据数组会导致bank冲突,但是如下所示的以下访问不会导致冲突。

no bank conflict

谢谢你的回答!!!

cuda conflict
2个回答
1
投票

https://developer.nvidia.com/blog/using-shared-memory-cuda-cc/

共享内存库冲突

为了实现并发访问的高内存带宽,共享内存被划分为可以同时访问的相同大小的内存模块(bank)。因此,跨越 b 个不同存储体的 n 个地址的任何内存加载或存储都可以同时得到服务,从而产生比单个存储体带宽高 b 倍的有效带宽。

但是,如果多个线程请求的地址映射到同一内存块,则访问将被串行化。硬件根据需要将冲突的内存请求拆分为多个单独的无冲突请求,从而将有效带宽减少等于冲突内存请求数量的系数。例外情况是,warp 中的所有线程都寻址相同的共享内存地址,从而导致广播。计算能力 2.0 及更高版本的设备具有多播共享内存访问的额外能力,这意味着扭曲中任意数量的线程对同一位置的多次访问是同时提供的。

假设您的并行缩减示例有 8 个大小为 4 字节的存储体。元素 i 由银行 i % 8 提供服务。

然后,银行 0,2,4,6 需要在第一个示例中服务两个请求。

在第二个示例中,每家银行只需处理一个请求。


0
投票

您肯定指的是这篇文章: https://developer.download.nvidia.com/compute/cuda/1.1-Beta/x86_website/projects/reduction/doc/reduction.pdf

首先,这些图仅显示 16 个 32 位整数的数组,并且线程数不超过 16 个,但您必须想象扩展示例以利用扭曲中的所有 32 个线程。

您的第一个示例不会产生任何存储体冲突,因为线程 #0 访问存储体 0 和 1,线程 #2 访问存储体 2 和 3,依此类推。线程#30将访问bank 30和31,奇数线程不被使用,所以没有bank冲突!

正如本文所强调的,存储体冲突仅发生在“reduction #2”的示例中,其中线程编号为 0、1、2 等。在这种情况下,存储体冲突不是由线程 #0 单独读取存储体 0 和 1 造成的按顺序执行,但通过线程 #16 的并行执行,该线程将同时读取数组的第 32 和 33 个元素,并且这些元素位于相同的存储体 0 和 1 上。 同样的冲突也会发生在线程 #1 和线程 #17 之间,依此类推。

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