共计 1409 个字符,预计需要花费 4 分钟才能阅读完成。
导读 | 我们谈到 GPU 相比 CPU 有更大的内存带宽,此言不虚,这也是众核 GPU 有源源不断数据弹药供给,能够发挥强大算力的主要原因。 |
在先前的文章中我们谈到 GPU 相比 CPU 有更大的内存带宽,此言不虚,这也是众核 GPU 有源源不断数据弹药供给,能够发挥强大算力的主要原因。如下表所示(GDDR 和 HBM 都是 GPU 的显存规格),基本上 GPU 的内存带宽要比 CPU 多一个数量级。
但是考虑到 GPU 运算核心的数量,平均下来显存带宽真的足够富裕吗? 参考资料 1 的《Memory bandwidth》文章提供了很有趣的视角,我们在这里介绍下。MOS 6502 发布于 1975 年,是微型计算机发展史上非常重要的一块芯片。6502 一般运行在 1M 时钟频率,每个时钟可以访问 1Byte 内存数据,6502 的一条指令需要花费 3~5 个时钟,所以平均下来每条指令大概可以获得 4B 内存数据。
与此相对照,Intel 的 Core i7-7700K 是一款目前比较主流的桌面 CPU,运行频率 4.2G,内存带宽大概 50GB/s。i7-7700K 一共有 4 个处理核心,所以每个核心大概可以均摊到 12.5GB/ s 的内存带宽,也就是每个时钟可以访问约 3B 的内存数据。该 CPU 的 IPC(Instruction Per Clock)为 1,极优化的代码可以达到的 IPC 为 3,按此计,每条指令可得 1B 的内存数据,跟老前辈 6502 相比,已经落后不少。更进一步,现代 CPU 支持 256 位长度的 SIMD 指令,每个时钟最多执行 3 条指令,类比 GPU,我们以 32 位为一个通道作为单独执行线程,这样每个时钟我们一共有 24 条指令执行,所以每条指令可以访问 0.125B 内存数据或者说每 8 条指令得到 1B 内存数据。
我们再回过头来看看 GPU 的情形。以 NVidia GeForce GTX 1080Ti 为例,内存带宽 484GB/s,处理单元工作频率为 1.48G,所以对整个 GPU 来说,每个时钟大概可以访问 327B 内存数据。这个 GPU 一共有 28 个 SM(类似 CPU 的处理核心),每个 SM 有 128 个 SP,所以总共有 3584 个 SP(类似先前 SIMD32 位通道)。这样每个 SM 一个时钟大概可以访问 11.7B 的内存数据,平均到 128 个 SP,一个 SP 一个时钟得到 0.09B 数据,换个好听的说法就是每 11 条指令可以得到 1B 内存数据,比 CPU 的指标还恶劣。
需要再次重申的是,因为设计目标的问题,CPU 其实更关注访存延迟指标,所以相形之下,内存带宽的压力对 GPU 更为显著。这也是为什么我们先前说过的 GPU 也开始配置多级 Cache 的原因,除了改善访存延迟,也可以降低内存带宽压力。另外我们在《GPU 历史之二三事》里也提到 Nvidia 和 AMD 都开始拥抱移动 GPU 常用的 TBR(Tile Based Rendering)的绘制技术,内存带宽的压力也应该是重要的驱动因素。而作为软件人员,在设计算法的时候,我们要重视算法的运算强度 (见《Roofline 模型初步》),要充分利用片上内存包括硬件 Cache 和软件 Cache(Shared Memory),以及注意内存的合并访问(Memory Coalescing) 等等来优化内存带宽。
主要参考资料:
https://fgiesen.wordpress.com/2017/04/11/memory-bandwidth/