ESC
输入关键词搜索文章
目录

并行计算核心主题

嵌入式智能系统与新型计算架构 · L02
为什么 2004 年之后,让程序变快的答案不再是等下一代 CPU?
CH01
程序员的困惑:性能从天而降的时代结束了
核心问题

如何让你的程序跑得更快?2004 年前的答案和 2004 年后的答案截然不同。

课件以一个看似简单的问题开场:How do you make your program run faster? 在 2004 年以前,答案几乎不用动脑筋——等六个月买台新机器就行了。CPU 主频从 10 MHz 到 200 MHz 再到 3 GHz 的狂飙,让每一代新处理器都自然而然地把旧程序推上新的性能台阶。程序员什么都不用做,性能就从天而降,这就是所谓的"免费午餐"。

但这个时代在 2004 年前后戛然而止。课件在 Slide 5 展示了一张极具说服力的趋势图:

PDFILP 耗尽与频率增长停滞p.5
正在渲染 PDF 第 5 页…
ILP 耗尽与频率增长停滞(PDF 第 5 页) · 打开原文

图上清晰可见四条曾经齐头并进的曲线开始分道扬镳:晶体管密度(Transistor density)仍在增长,而时钟频率(Clock frequency)、功耗(Power)、指令级并行度(ILP)三条曲线几乎同时触及天花板。C++ 大师 Herb Sutter 在 2005 年发表于 Dr. Dobb's Journal 的经典文章《The Free Lunch Is Over》中正式宣告了这一转折:处理器厂商已经几乎穷尽了所有传统方法来提升单核性能,未来的性能增长必须依赖并行计算。

"铁律"(Iron Law)

单处理器性能的铁律将执行时间分解为三个正交维度:指令数(由算法、编译器和 ISA 决定)、CPI(由微架构决定)、时钟周期(由制程工艺决定)。在 2004 年之前,三者的改善共同驱动了指数级的性能增长;此后,时钟频率停滞、CPI 的下降也因 ILP 耗尽而趋缓,留给程序员的只剩一条路:利用更多处理单元。

回顾处理器性能演进的历史,可以看到几个关键的里程碑:数据通路从 4 位扩展到 64 位,流水线效率从 3.5 CPI 优化到 1.1 CPI,超标量处理器每周期发射最多 4 条指令,乱序执行从指令流中挖掘并行性。这些技术共同推动了上世纪 80 到 90 年代的大幅性能飞跃。然而到了 2004 年左右,这些手段的边际收益急剧递减,处理器设计哲学发生了根本性转变。

CH02
功耗墙:Dennard 缩放定律的终结
核心问题

为什么不能继续提高时钟频率?功耗是终极约束。

频率增长的背后有一道不可逾越的物理屏障——功耗。课件用一张"功耗墙"(Power Wall)的图阐明了这一点,同时展示了风冷、液冷、TPU 和 GPU 等现代硬件对散热问题的应对。

PDF功耗墙:散热约束下的设计极限p.6
正在渲染 PDF 第 6 页…
功耗墙:散热约束下的设计极限(PDF 第 6 页) · 打开原文

理解功耗墙,需要从 Dennard 缩放定律说起。1974 年,Robert Dennard 发表了关于 MOSFET 晶体管缩放的开创性论文,核心结论是:当晶体管尺寸按比例缩小时,工作电压和电流也会同比例缩小,使得芯片单位面积的功耗密度保持恒定。这意味着每一代新制程可以在不增加功耗的前提下集成更多晶体管、运行在更高频率——完美的正反馈循环。

然而到了 2005 年前后,这一规律失效了。原因在于 Dennard 缩放基于一个关键假设:阈值电压可以随工作电压一起线性缩小。但量子隧穿效应和亚阈值漏电使得阈值电压无法继续降低,导致工作电压的缩放速度远慢于晶体管尺寸的缩放速度。

处理器的功耗由两部分组成:

动态功耗(Dynamic Power):晶体管在开关切换时消耗的能量,公式为:

$$P_{\text{dynamic}} = \alpha \cdot C \cdot V^2 \cdot f$$

其中 $\alpha$ 是活动因子(每个时钟周期翻转的晶体管比例),$C$ 是电容负载,$V$ 是工作电压,$f$ 是时钟频率。注意电压 $V$ 是平方项——电压降低 30%,功耗就能降低约 50%。这正是 Dennard 缩放之所以有效的数学基础。

静态功耗(Static Power):即使晶体管不翻转,漏电流(Leakage Current)也会持续消耗功率:

$$P_{\text{static}} = I_{\text{leak}} \cdot V$$

随着制程节点缩小到纳米级,栅极绝缘层越来越薄,量子隧穿导致的漏电电流急剧上升。在早期的微米制程中,静态功耗几乎可以忽略;但在现代 5nm、3nm 工艺下,静态功耗已占到总功耗的 30% 甚至更高。

功耗墙的直接后果

频率无法继续提升不是因为做不到,而是因为散热做不到。风冷方案的热设计功耗(TDP)通常在 100-250W 范围,液冷可以提高到 350-400W,但物理极限已经近在咫尺。与其让一个核心跑在 6GHz 发烫到不可收拾,不如把同样的芯片面积分成四个 3GHz 的核心,总吞吐量反而更高。这正是多核架构诞生的根本逻辑。

CH03
三种并行层次:ILP、DLP 与 TLP
核心问题

并行计算不是一种技术,而是三个层次的系统化策略。

课件在回顾处理器性能历史时,实际上已经触及了三种不同层次的并行。理解它们的区别对于把握现代处理器设计至关重要。

ILP(Instruction-Level Parallelism,指令级并行)是最底层的并行形式,发生在单个 CPU 核心内部。超标量(Superscalar)处理器可以在一个时钟周期内同时发射多条指令,乱序执行(Out-of-Order Execution)则通过硬件动态分析指令间的数据依赖关系,在保持程序语义正确的前提下重新排列执行顺序,最大化功能单元的利用率。分支预测(Branch Prediction)技术通过猜测条件跳转的方向来减少流水线气泡。这些技术对程序员完全透明,由硬件自动完成。

然而 ILP 的挖掘存在天花板。真实程序中固有的数据依赖和控制依赖限制了可提取的并行度。课件展示的曲线表明,ILP 在 2000 年前后已基本耗尽,此后无论怎样增加硬件复杂度,单核 CPI 的下降都极为有限。

DLP(Data-Level Parallelism,数据级并行)针对的是同一条操作同时作用于一批数据的情况。SIMD(Single Instruction, Multiple Data)指令是 DLP 的典型实现:一条指令同时对多个数据元素执行相同的运算。ARM 的 NEON 指令集、x86 的 AVX/SSE 指令集、GPU 的 SIMT 执行模型都属于 DLP 范畴。

DLP 特别适合矩阵运算、图像处理、信号处理等数据规整的场景。在深度学习爆发后,DLP 的价值被进一步放大——神经网络的推理和训练本质上是大规模矩阵乘法和向量运算,天然契合 SIMD 执行模式。

TLP(Thread-Level Parallelism,线程级并行)是程序员最直观感受到的并行形式:多个线程在多个处理器核心上同时执行。TLP 是多核架构(Multi-core)和多线程(Multi-threading)的基础。与 ILP 和 DLP 不同,TLP 需要程序员显式地将程序分解为可并行执行的线程,并处理线程间的通信和同步问题。

课件展示了 TLP 在不同平台上的实现:

  • 服务器与云端:Intel Xeon Sapphire Rapids(2022),最高 72 核 / 144 线程
  • GPU 计算:NVIDIA H100(2022),4nm 工艺,数千 CUDA 核心
  • 嵌入式边缘:NVIDIA Jetson Nano(4 核 ARM Cortex-A57 + 128 核心 CUDA GPU)
从 ILP 到 TLP 的设计范式转变

2004 年之前的设计哲学是"在给定的芯片面积内最大化单核性能",方法包括更激进的推测执行和更大的缓存。2004 年之后,设计目标转变为"最大化每单位面积的性能"(Performance Per Area)和"最大化每瓦性能"(Performance Per Watt)。这意味着与其把硅片面积花在越来越复杂的单核上,不如切分成多个简单核心,以面积和功耗换吞吐量。

CH04
Amdahl 定律:串行比例决定加速上限
核心公式

加速比的上限由程序中不可并行化的部分决定,而非处理器数量。

有了并行硬件,性能就能无限提升吗?Gene Amdahl 在 1967 年给出了否定的回答。Amdahl 定律指出,如果一个程序中只有比例 $P$ 的部分可以并行化,其余 $(1-P)$ 必须串行执行,那么使用 $N$ 个处理器所能获得的最大加速比为:

$$S(N) = \frac{1}{(1 - P) + \frac{P}{N}}$$

直觉上很好理解:当处理器数量 $N$ 趋向无穷大时,$\frac{P}{N}$ 趋近于零,加速比趋向于 $\frac{1}{1-P}$。也就是说,串行比例 $(1-P)$ 是加速比的硬性天花板,再多的处理器也无法突破。

举一个具体的例子:假设程序中有 95% 的部分可以并行化($P = 0.95$),那么无论使用多少个处理器,加速比都不会超过:

$$S_{\max} = \frac{1}{1 - 0.95} = 20$$

即使你有一百万个核心,加速比也只能是 20 倍。这就是 Amdahl 定律的冷酷之处——它告诉我们,并非所有的并行化投入都有回报。

课件通过一个课堂实验(DEMO)生动地展示了这一原理。在实验中,学生模拟处理器节点进行求和运算。当节点数从两个增加到四个时,加速比确实提升了,但提升幅度低于线性比例,因为节点间的通信(交换部分和)引入了额外开销。实验进一步揭示:当问题规模较小时,通信和同步的开销可能完全吞噬并行化带来的收益。

课堂实验的三个关键观察

实验一:加速比实现了,但通信开销限制了理想的线性加速。
实验二:负载不均衡导致部分节点闲置,限制了整体加速比。
实验三:当内存访问延迟相对于计算占主导时,并行加速的效果更为有限。

CH05
Gustafson 定律:问题规模可以随之增长
核心问题

Amdahl 定律是悲观的,但它是唯一的视角吗?

Amdahl 定律假设问题的总规模固定不变,只是用更多的处理器来更快地解决同一个问题。但在实际场景中,人们获得更强大的计算能力后,往往会选择解决更大的问题——而不是用更短的时间解决同样大小的问题。

1988 年,John Gustafson 提出了另一种视角:假设串行部分的执行时间保持不变,而并行部分的计算量随处理器数量线性增长。设串行执行时间为 $s$,每个处理器上的并行执行时间为 $p$,则使用 $N$ 个处理器时,加速比为:

$$S_{\text{Gustafson}}(N) = \frac{s + N \cdot p}{s + p}$$

与 Amdahl 定律不同,这个加速比随着 $N$ 的增长可以无限增大,不受串行比例的硬性约束。Gustafson 的论点是:既然我们总是在用更多的算力来解决更大的问题,那么"固定问题规模"这个前提本身就是不现实的。

这两个定律并不矛盾,而是从不同角度审视并行计算的收益:

  • Amdahl 定律适用于固定问题规模的场景,回答"用更多处理器能把同一个问题解多快",给出了加速比的上界。
  • Gustafson 定律适用于可扩展问题的场景,回答"用更多处理器能解决多大的问题",展现了并行计算的真正潜力。

在科学计算、深度学习等领域,Gustafson 定律的视角更符合实际:研究者总是希望用更多的 GPU 来训练更大的模型,而非更快地训练同样大的模型。

CH06
并行计算的三大开销
核心问题

理论加速比和实际加速比之间的差距从何而来?

即使一个程序有大量可并行化的部分(Amdahl 定律允许),且有足够大的问题规模(Gustafson 定律支持),实际加速比仍然会低于理论预期。原因在于并行计算引入了三种不可忽视的额外开销。

通信开销(Communication):多个处理器协作完成一个任务时,必然需要交换数据。在分布式系统中,处理器之间通过网络传输消息;在片上多核系统中,数据通过片上互联网络或共享缓存传递。无论哪种方式,通信都需要时间和能量。课件中的课堂实验清楚地表明:让学生("处理器")彼此靠近、甚至大声喊出部分和,都能显著减少通信延迟。

同步开销(Synchronization):当多个线程访问共享数据时,必须通过同步原语(锁、屏障、原子操作等)来保证数据一致性。同步本质上是一种"等待"——某个线程必须停下来等另一个线程完成操作。这种等待在单线程程序中不存在,却是并行程序的固有成本。

负载均衡(Load Balancing):理想情况下,所有处理器应该在同一时刻完成各自的任务。但现实中的工作负载往往不均匀——某些任务天然比其他任务耗时更长。如果 10 个处理器中有 9 个已经完成,只剩下 1 个还在计算,那么整体加速比就被那个最慢的节点拖住了。课件中的 DEMO 2 直接展示了这一问题:部分学生很快完成了分配到的求和任务,而另一些学生还在计算,导致前者闲置等待。

并行编程的原则清单

课件总结了并行计算的核心原则:寻找足够的并行性(Amdahl 定律)、选择合适的粒度(每个并行任务的规模)、利用数据局部性(移动数据的成本远高于计算)、保持负载均衡、协调同步与共享数据。这五项原则构成了后续课程中优化并行程序的方法论基础。

CH07
案例:Apple A15 与异构并行
核心问题

"免费午餐"结束后,真实的移动端芯片是如何做并行设计的?

课件展示了一组当代处理器芯片的照片,从 Intel Xeon 服务器到 NVIDIA H100 GPU,再到嵌入式设备。其中 Apple A15 Bionic 是一个极具代表性的异构并行案例。

Apple A15(iPhone 13 Pro,5nm 工艺)的架构如下:

  • 6 个 CPU 核心(3.23 GHz):采用大小核设计,2 个高性能核心(Avalanche)+ 4 个高能效核心(Blizzard),通过 ARM 的 big.LITTLE 架构实现性能与功耗的动态平衡
  • 5 个 GPU 核心:负责图形渲染和通用并行计算,数据级并行(DLP)的主力
  • 16 核 NPU(Neural Engine):专为神经网络推理设计的加速器,每秒可执行 15.8 万亿次运算(15.8 TOPS)

A15 的设计体现了 2004 年后处理器设计的核心哲学:不再追求单一通用核心的极致性能,而是通过异构并行(Heterogeneous Parallelism)让不同类型的计算任务落在最适合它的硬件上。CPU 处理通用逻辑与控制密集型任务,GPU 处理数据并行度高的图形和通用计算,NPU 专门加速神经网络的矩阵运算。这种"术业有专攻"的策略,正是应对功耗墙的最优解。

课件还提到了 NVIDIA Jetson Nano(4 核 ARM + 128 核心 CUDA GPU)和 Raspberry Pi(四核 ARM)等嵌入式平台。这些设备的共同特征是:在有限的功耗预算下,通过 TLP 和 DLP 的组合来最大化有效计算能力。

Fast ≠ Efficient

课件特别指出一个容易忽视的问题:程序跑得更快并不意味着硬件被高效利用。在 10 个处理器的系统上获得 2 倍加速比是一个"好"结果吗?答案取决于效率——如果理论上应该得到 8 倍加速,那 2 倍说明程序的并行化质量很差。从硬件设计者的角度看,选择正确的功能单元组合(性能/面积比、性能/功耗比)与从程序员的角度写出好的并行代码同样重要。

CH08
"硬件之上的空间":后摩尔时代的性能来源

课件最后引用了 2020 年发表在 Science 上的论文《There's Plenty of Room at the Top: What Will Drive Computer Performance After Moore's Law?》(Leiserson et al.),以一个简单的矩阵乘法示例说明:即使硬件不再变快,软件和算法层面仍有巨大的优化空间。

一个 4096×4096 的矩阵乘法,朴素三重循环实现与经过缓存分块(Cache Blocking)、SIMD 向量化、多线程并行化后的实现,性能差距可达数十倍甚至上百倍。这些优化全部发生在"硬件之上"——算法层、编译器层、运行时层——不需要等待下一代芯片。这正是本课程的核心命题之一:在硬件增长放缓的时代,软件和算法的优化成为性能提升的主要驱动力。

课后思考
开放性问题
  1. 串行比例的真实含义:在实际工程中,一个程序的"串行比例"如何测量?是否存在某些看似必须串行的操作,实际上可以通过算法重构实现并行化?考虑数据库事务的并发控制或编译器的类型检查过程。
  2. Amdahl vs. Gustafson 的决策边界:在什么场景下应该用 Amdahl 定律来评估项目可行性,在什么场景下 Gustafson 定律更合适?如果一家公司要建设大规模 AI 训练集群,应该采用哪种评估框架?
  3. 功耗效率的极致:Dennard 缩放失效后,除了多核和异构计算,还有哪些技术路径可以应对功耗墙?考虑近阈值计算(Near-Threshold Computing)、忆阻器(Memristor)、光互连(Optical Interconnect)等前沿方向。
  4. 并行编程的困难根源:课件指出并行编程比串行编程困难得多。这种困难的本质是什么——是人类的思维模式天然偏串行,还是并行问题本身的复杂性决定的?大语言模型(LLM)能写出高质量的并行代码吗?