南京大学 操作系统 (JYY) 学习笔记:CPU 的局限、GPU 与 AI 时代的算力革命
写在前面:这是本系列的第十九篇。
背景回顾:并发编程的基础机制(线程、互斥锁、条件变量、信号量等)足够实现高效的并发/并行编程,但它们的正确使用完全由使用者负责——这毫无疑问是个过于乐观的假设。因此,编程语言的设计者们在不同的应用场景下,实现了许多特定的并发/并行编程机制(如 OpenMP、JS 的事件模型、Go 的协程等)。
与此同时,人们也开始发现,对于一些特别的应用场景(如图形渲染、深度学习),传统的 CPU 和多线程也许并不是最“高效”的解决方法。
本讲内容:我们将跳出纯软件的范畴,探讨 CPU 的物理局限,以及加速器(GPU)和人工智能背后的极客并行编程。

熟悉又陌生的 CPU (Spicy 🌶️)
什么是 CPU?
概念:无情执行指令的机器
- 比如我们在
mini-rv32ima中看到的MiniRV32IMAStep()循环。 - 指令集(Instruction Set)是硬件能够理解的语言,是计算机执行操作的基础;汇编语言则是它的符号化表示。
实际的现代 CPU:Instruction-level Parallelism (指令级并行)
- 现代 CPU 有多个核心,共享内存,并采用了极其复杂的弱内存模型 (Relaxed Memory Model)。为了保证正确性,必须引入
fence,atomic等指令实现内存一致性控制。 - 但你可能没有想到的是:其实你写的每一行单线程代码,一直都在(被自动地)并行编程!
- 每个 CPU 核心内部,其实都藏着一个极度复杂的“硬件编译器”。
- 它在运行时进行动态的数据流分析和指令调度(乱序执行)。
- 在顶级的服务器 CPU 上,可能同时有上千条指令在并行执行!
- 科普:IPC(Instruction Per Clock,每时钟周期指令数)。CPU 的最终算力 = IPC × 频率。
这意味着什么?
在“能效”和“性能”之间,CPU 坚定地选择了后者。
- 跑得越快,浪费得越多。每一个门电路的翻转都会产生热量。
- CPU 里的那个硬件“编译器”(分支预测、乱序调度单元)会消耗巨量的电能。
- 这些能量使得你的计算任务能“尽快完成”(极低的延迟),但这绝不等于“单位时间内完成尽可能多的计算”(吞吐量不高)。
Dark Silicon(暗硅时代)与功耗墙
P=C⋅V2⋅fP = C \cdot V^2 \cdot fP=C⋅V2⋅f
(功耗 = 电容 ×\times× 电压的平方 ×\times× 频率)
- “功耗墙”: 纵使我们能把晶体管做得再小,把电路做得再大,散热和热功耗的物理极限也死死地限制了 CPU 的性能上限。芯片上很大一部分区域因为功耗限制,甚至不敢通电(这就是暗硅)。
面对功耗墙:寻找新出路
如何在降低电压 VVV 和频率 fff 的同时,用“芯片面积”换取“性能”?
出路 1:让一条指令能处理更多的数据
- SIMD (Single Instruction, Multiple Data):
- CPU 执行“一条指令”所浪费的解析和调度能量大致是固定的。
- 如果这条指令能同时处理更多的数据,浪费的比例就越小!
出路 2:用更多、更简单的处理器
- 发展多处理器系统、异构多处理器(大小核架构)。
- 在同等的芯片面积下,如果把复杂的乱序执行单元砍掉,处理器越简单,能塞进去的数量就越多!
极致演进:SIMD 与数据并行
Single Instruction, Multiple Data (SIMD)
可以一次性让一条指令对连续的操作数做相同的运算!
比如,用一条指令对 4 个 float 同时做 4 次乘法。
经典的 Intel MMX (MultiMedia eXtension) 技术就是为此而生的:
(奔腾 MMX 处理器的辉煌时代)
实现方式:增加一些“超大”的寄存器
- 引入了 64-bit 的
mm寄存器。 - 增加了几十条专门实现 “packed register” 操作的指令。
军备竞赛:MMX →\rightarrow→ SSE →\rightarrow→ AVX →\rightarrow→ AVX-512
- 寄存器宽度疯狂翻倍: 64 (
mm) →\rightarrow→ 128 (xmm) →\rightarrow→ 256 (ymm) →\rightarrow→ 512 (zmm)。 - 数据类型支持: 从
int8/16/32扩展到float32和float64。 - 更多的高级运算 (三操作数模式):
- Shuffle (洗牌): c[i]=a[b[i]]c[i] = a[b[i]]c[i]=a[b[i]]
- FMA (融合乘加): a×b+ca \times b + ca×b+c,一条指令瞬间完成!
为什么 SIMD 没能完全解决问题?
- SIMD 指令依然是在 CPU 内部调度的,它必须参与到 CPU 复杂的缓存和动态流水线中。
- 寄存器宽度不能做得太宽,否则遇到短数组就会造成极大的浪费,并行度终究有限。
我们实在是太想要性能了!只能选择横向扩展:
- 单 CPU →\rightarrow→ 多 CPU →\rightarrow→ 大小核 CPU。
同等面积可以放置更多“高能效”计算单元:
- 比如 Apple M1: 4 Performance + 4 Efficiency。
- 核心 Trick:降低频率 = 降低所需电压(功耗与电压的平方成正比),从而实现极致的“热功耗分配”。
GPU 和 GPGPU 的崛起 (Spicy 🌶️)
生于娱乐,长于智能。
记得刚才的想法吗?
- 用更多更简单的处理器!
- 同等面积,处理器越简单,数量越多。
- 我们甚至不需要处理器有完整的 CPU 指令集计算能力!
于是诞生了“领域专用加速器”:
- ISP: Image Signal Processing (手机相机处理)
- GPU: Graphics Processing Unit (图形渲染)
- DPU: Data Processing Unit (网络/数据处理)
终于有一件事可以让专用处理器来做了:画图!
对屏幕像素 (i,j)(i, j)(i,j) 的计算,天生就是 “Massive Parallel” (海量并行) 的!
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x)
putchar(f(x, y) ? '*' : ' ');
putchar('\n');
}
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐
所有评论(0)