1. 课程导入与性能优化全景

MATLAB 之所以能在工程计算领域长期占据核心位置,很大程度上得益于它把矩阵运算、可视化与算法开发整合在同一套交互环境里。但当问题规模从“几千个点”增长到“上亿个点”,从“单次仿真”变成“参数扫描”或“训练迭代”时,单纯依赖 for 循环和默认的串行执行方式,计算时间会迅速成为瓶颈。本课程要解决的核心问题就是:如何在不牺牲 MATLAB 开发效率的前提下,把计算任务合理地分配到多核 CPU、GPU 以及多机集群上,并获得可度量的加速收益。

一、并行与 GPU 加速到底解决什么问题

MATLAB 中的性能瓶颈通常来自三类场景。第一类是大规模逐元素运算,例如对一张 8000×8000 的矩阵做滤波、阈值处理或逐点函数映射,这类任务天然适合向量化和 GPU 并行。第二类是可独立拆分的重复计算,例如对 200 组不同参数分别求解同一个微分方程,每组之间没有数据依赖,适合用 parfor 分配到多个 worker。第三类是计算密集但数据可驻留显存的任务,例如深度学习前向/反向传播、大规模矩阵乘法、FFT 与卷积,这类任务在 GPU 上往往能获得数十倍加速。

需要强调的是,并行不是“万能加速键”。如果任务本身只运行 0.05 秒,而启动并行池或传输数据需要 2 秒,那么并行反而更慢。因此判断是否值得并行,关键看三个量:单次计算耗时、任务可拆分程度、数据搬运开销。一个实用的经验判据是:当单次核心计算超过 0.1~1 秒、且各子任务相互独立时,并行收益通常开始显现;GPU 加速则要求数据规模足够大,使计算时间明显超过主机与设备之间的传输时间。

二、MATLAB 并行与 GPU 工具链全景

MATLAB 提供了一条从“单机多核”到“GPU”再到“集群”的渐进式工具链,理解它们的分工是后续学习的基础。下图给出了这条工具链的整体结构,以及各类任务与对应工具的映射关系。

MATLAB 并行与 GPU 加速工具链全景 任务类型 逐元素 / 矩阵运算 独立参数扫描 迭代 / 训练循环 大规模数据 / 集群作业 核心工具 向量化 + gpuArray arrayfun / pagefun 隐式扩展 parfor / parfeval Parallel Pool spmd / distributed GPU 深度学习 dlarray / trainnet 自动多 GPU Parallel Server / Cloud batch / job / task 集群 Profile 执行硬件 多核 CPU 本地 Worker 进程 NVIDIA GPU 集群 / 云节点 选择原则 先向量化 → 再判断是否并行 → 数据规模大且计算密集时上 GPU → 需要超多任务或超大数据时用集群

从图中可以看到,工具选择遵循一条清晰的递进逻辑:先向量化,再并行,最后上 GPU 或集群。向量化是成本最低、收益最直接的第一步,它不需要任何额外硬件,只是把循环改写成矩阵运算。只有当向量化之后仍然太慢,才考虑引入并行池;只有当数据规模和计算密度都足够大时,GPU 才真正发挥优势。

三、一个可对照的示例:热扩散迭代

为了把“加速收益”变成可观察的量,这里给出一个贯穿课程的示例任务:对 2048×2048 的二维温度场做 500 次五点差分迭代。串行版本的核心循环如下:

n = 2048; T = zeros(n); T(1,:) = 100; T(end,:) = 0;
for k = 1:500
    T(2:end-1,2:end-1) = 0.25 * ( ...
        T(1:end-2,2:end-1) + T(3:end,2:end-1) + ...
        T(2:end-1,1:end-2) + T(2:end-1,3:end));
end

在典型 8 核 CPU 上,这个串行版本大约需要数秒到十几秒(具体取决于机器)。如果改用 gpuArray,只需把初始矩阵搬到显存:

T = gpuArray(zeros(n));
% 循环体不变,运算自动在 GPU 上执行
T = gather(T);   % 结果取回主机

此时每次迭代的四个矩阵加法与一次乘法都在 GPU 上并行完成,2048×2048 共约 419 万个元素,足以让 GPU 的数千个核心保持忙碌。判断加速是否成功,不能只看“感觉快了”,而应使用 gputimeit 或 timeit 做多次测量取中位数,并对比 gpuDevice 报告的显存占用,确认没有因为数据溢出显存而触发隐式回传。

测量 GPU 性能时,第一次调用往往包含内核编译与显存分配开销,必须预热一到两次后再计时,否则会得到偏大的结果。同时注意 gather 本身有传输成本,应尽量让整个计算链留在 GPU 上,最后只取回必要结果。

四、学习路径与常见误区

本课程后续内容将沿着“诊断瓶颈 → 向量化 → 多核并行 → GPU 编程 → 性能度量与调优”的顺序展开。建议的学习路径是:先掌握用 tic/toc、timeit、Profiler 定位热点;再练习把循环改写为矩阵运算;然后学习 parfor 的适用条件与变量分类;接着进入 gpuArray、arrayfun、pagefun 等 GPU 编程接口;最后学习多 GPU、集群与深度学习加速。

需要提前警惕几个常见误区。其一,把并行当成默认选项,对小任务启动并行池,结果总时间反而增加。其二,在 parfor 中频繁访问大数组或做文件读写,导致通信开销吞掉计算收益。其三,GPU 上使用不支持的函数,MATLAB 会静默回退到 CPU 执行,表面能跑通,实际没有加速。其四,只测一次就下结论,忽略了缓存、预热和系统负载带来的波动。理解这些边界,比记住某个函数名更重要。

性能优化的本质不是“用上并行”,而是“用对并行”。每一次加速决策都应建立在测量之上:先知道时间花在哪里,再决定用哪种工具,最后用可重复的计时验证收益。