2. 并行计算基础

并行计算并不是简单地把任务“分给多个核”,它首先是一套关于任务如何分解、执行体如何协作、数据如何流动、性能如何度量的系统方法。理解并行计算模型、Flynn分类、加速比与效率、Amdahl定律与Gustafson定律,是后续学习CPU多线程、GPU大规模线程和FPGA流水线并行的共同基础。

一、并行计算模型:从任务到执行体

并行计算模型描述“计算如何被组织”。常见模型包括:

  • 数据并行模型:同一操作作用于不同数据分片,例如向量加法、GPU的SIMT执行。
  • 任务并行模型:不同任务彼此独立或弱耦合,例如多线程处理不同请求。
  • 共享内存模型:多个执行体访问同一地址空间,通过锁、原子操作或屏障同步。
  • 消息传递模型:执行体拥有私有内存,通过发送/接收消息通信,典型如MPI。
  • 流水线模型:任务按阶段串接,数据像流水一样逐级推进,FPGA中尤为常见。

这些模型并非互斥。一个异构程序可能同时包含:CPU端任务并行、GPU端数据并行、FPGA端流水线并行,以及跨设备的消息传递。

二、Flynn分类:按指令流与数据流划分

Flynn分类从指令流和数据流两个维度描述计算机体系结构:

类别含义典型代表
SISD单指令流单数据流传统单核CPU
SIMD单指令流多数据流向量指令、GPU线程束
MISD多指令流单数据流理论模型,实际少见
MIMD多指令流多数据流多核CPU、多节点集群

GPU通常被归入SIMT(单指令多线程),它是SIMD的扩展:多个线程执行同一指令,但可拥有独立寄存器状态和分支路径。FPGA则更灵活,可同时实现SIMD、流水线和MIMD式控制逻辑。

三、加速比与效率:并行到底赚了多少

设串行执行时间为 T_s,并行执行时间为 T_p,处理器数量为 p,则:

加速比 S = T_s / T_p
效率 E = S / p = T_s / (p * T_p)

理想情况下,S = p,E = 1。但实际中,通信、同步、负载不均和串行部分都会降低效率。例如,8个核运行一个程序,串行时间10秒,并行时间2秒,则 S = 5,E = 5/8 = 62.5%。这说明“核多”不等于“快得多”。

加速比衡量“快了多久”,效率衡量“资源用得好不好”。两者必须结合看:高加速比可能来自大量低效核,高效率也可能因规模太小而收益有限。

四、Amdahl定律与Gustafson定律

Amdahl定律关注固定问题规模下,串行部分对加速比的上限约束。设可并行比例为 f,串行比例为 1-f,则:

S(p) = 1 / ((1 - f) + f / p)

当 p → ∞,S_max = 1 / (1 - f)。若程序有20%必须串行,则无论多少核,加速比最多为5。这是并行优化中最容易被忽视的“天花板”。

Gustafson定律则关注问题规模随处理器增加而扩大的场景。设并行部分随规模扩展,则:

S(p) = p - α(p - 1)

其中 α 为串行比例。它说明:如果问题规模能同步扩大,并行系统仍可获得接近线性的加速。Amdahl偏“固定规模”,Gustafson偏“扩展规模”,二者共同解释了为什么大规模计算更看重可扩展性。

并行计算基础:模型 → 分类 → 性能度量 并行计算模型 • 数据并行 • 任务并行 • 共享内存 / 消息传递 • 流水线并行 Flynn分类 SISD:单核CPU SIMD:向量 / GPU MISD:理论模型 MIMD:多核 / 集群 性能度量 加速比 S = Ts / Tp 效率 E = S / p 串行比例 α 通信 / 同步开销 Amdahl定律 固定问题规模 S(p) = 1 / ((1-f) + f/p) 串行部分决定上限 例:20%串行 → 最大S=5 关注“固定规模加速” Gustafson定律 问题规模随处理器扩展 S(p) = p - α(p - 1) 并行部分可随规模增长 大规模计算更关注可扩展性 关注“扩展规模加速” 核心结论:并行模型决定“怎么分”,Flynn分类决定“怎么执行”,Amdahl/Gustafson决定“能快多少”

五、案例:矩阵乘法的并行分解

以 C = A × B 为例,若矩阵规模为 N×N:

  • 数据并行:每个线程计算 C 的一个元素,GPU中可映射为大量线程。
  • 任务并行:按行或按列分块,不同线程块处理不同子矩阵。
  • 流水线并行:FPGA中可将乘加、累加、写回分成多级流水。

若串行部分占10%,Amdahl上限为10倍;但当矩阵规模扩大10倍,Gustafson视角下可接近线性加速。这说明:并行策略必须与问题规模、硬件形态和通信代价匹配。

六、常见误区与复盘

误区1:核越多越快。若串行比例高、通信开销大,增加核数反而可能降低效率。

误区2:只看加速比,不看效率。用32核获得8倍加速,效率仅25%,资源浪费严重。

误区3:把GPU的SIMT等同于SIMD。SIMT允许线程级分支,但分支发散会显著降低吞吐。

误区4:忽略Amdahl与Gustafson的适用边界。固定规模看Amdahl,扩展规模看Gustafson,二者不是互相否定,而是不同假设下的结论。

复盘时建议按以下清单检查:

  1. 任务是否可分解为独立或弱耦合子任务?
  2. 数据依赖是否允许并行?是否存在必须串行的关键路径?
  3. 通信、同步、内存带宽是否成为瓶颈?
  4. 加速比和效率是否随核数增加而合理变化?
  5. 问题规模扩大后,性能是否仍可扩展?

掌握这些基础后,后续无论是CPU多线程、GPU核函数还是FPGA流水线设计,都可以用同一套语言描述:模型决定分解方式,Flynn分类决定执行形态,加速比与效率衡量收益,Amdahl与Gustafson界定上限与扩展空间。