AI硬件06-揭秘训练芯片灵魂:脉动阵列如何让算力起飞,训练芯片算得快的真正秘密
本文为《AI 硬件体系深度调研》系列第 06 篇。上一篇我们拆开了训练芯片的五大模块,其中"张量计算核心阵列"被比作算力的发动机。但发动机为什么快?答案就藏在一个叫"脉动阵列"(Systolic Array)的架构里。本篇就把这个"灵魂"单独拎出来,讲透它凭什么能甩传统架构一个数量级。
黄金 100 字开头
你是否想过:同样做矩阵乘法,为什么 AI 芯片能甩 CPU 几条街?多数文章只说"并行",却没讲清芯片内部数据到底怎么流动的。本文用"泵血"般的比喻,把脉动阵列这个训练芯片的灵魂讲透。
一、什么是脉动阵列
先说结论:训练芯片的核心算力支撑,是一种叫"脉动阵列"(Systolic Array)的架构,它从根本上区别于 CPU 那样的通用芯片。
1.1 名字里的"脉动"
“Systolic"这个词源自生理学里的"心脏收缩”。心脏一跳一跳地收缩,把血液有节奏地泵向全身——这就是"Systolic"的本意。脉动阵列借用了这个比喻:数据像血液一样,在计算单元之间有节奏地、一波一波地流动,而不是像传统芯片那样,由控制单元一次次"发号施令"去取数、去算、再存回。
这个名字不是随便起的。脉动阵列的提出者、计算机科学家孔祥重(H.T. Kung)在 1970 年代末研究并行计算时,发现了一个反直觉的规律:计算的瓶颈常常不在"算",而在"搬运数据"。于是他设计了一种让数据"流动"起来的架构,并特意用"心脏泵血"来命名,强调数据有节奏、可预测的流动特性。
1.2 它和通用芯片的根本区别
CPU 这类通用芯片,遵循的是"取指令—取数—计算—写回"的串行节奏,每一步都由控制单元显式指挥。哪怕 CPU 内部也做了流水线和多核并行,它的基本哲学依然是**“程序计数器驱动、控制单元调度”**。
而脉动阵列的哲学完全不同:它把"控制"这个环节极度简化,让数据自己按固定的路径流进流出。阵列里没有复杂的指令解码、分支预测、乱序执行——这些东西在脉动阵列里统统不存在。它只做一件事:让数据按节拍流动,边流边算。
打个比方:CPU 是"一个调度员指挥一群工人",每个动作都要喊口令;脉动阵列是"一条自动流水线",零件放上去,自动经过每个工位完成加工。后者少了"指挥"的开销,自然更快。
1.3 为什么叫"阵列"
脉动阵列的物理形态,是一个规则的二维网格——横竖成行成列,整整齐齐。网格上的每个交叉点,放一个"处理单元"(Processing Element,简称 PE)。
- 规则排列:PE 们像棋盘格一样排成矩阵,没有特殊单元、没有例外;
- 独立执行 MAC:每个 PE 都是一个独立的小计算器,专门做"乘加"(MAC,Multiply-Accumulate);
- 只和邻居通信:每个 PE 只和它上、下、左、右的邻居交换数据,不跨单元乱跑。
这种"规则 + 局部 + 独立"的三重特性,让脉动阵列极其适合在硅片上大规模铺开——因为规则的阵列最容易设计、最容易布线、最容易验证。
现实中的阵列规模有多大?谷歌第一代 TPU 的脉动阵列是 256×256 个 PE,也就是 65536 个乘加单元排成一个正方形。这意味着一个权重值从顶部流到底部,沿途会被 256 个 PE 依次复用——加载一次、算 256 次。到了今天,主流训练芯片的阵列边长普遍在 128 到 512 之间,阵列越大,单次加载换来的复用次数就越多,搬运开销的占比就越低。
更重要的是,规则阵列带来一个巨大的工程红利:可扩展性。设计者要放大算力,不需要重新设计一套复杂逻辑,只需把 PE 网格多画几行几列,布线、验证、时钟树都能按模板复制。这就像搭积木——想变大,多拼几块相同的积木就行,不需要重新发明一块积木。这种"复制即扩展"的能力,是通用芯片靠堆核心很难做到的,因为核心之间还要复杂的缓存一致性、任务调度和总线仲裁。
⚠️ 避坑警告:脉动阵列不是"某一种芯片型号",而是一种架构模式。谷歌的 TPU、苹果的 NPU、英伟达的张量核心,底层都用了脉动阵列或它的变体。所以你会看到不同厂商的芯片都提"Systolic Array"——它们说的是同一种思想。
二、PE 单元与"波浪式"数据流
理解了脉动阵列是"PE 排成的网格",下一步就要看清楚:数据在这个网格里,到底是怎么流动的。
2.1 PE:阵列里的"心脏细胞"
每个 PE 的内部结构非常简单:一个乘法器、一个加法器、几个寄存器。它每个时钟周期只做一件标准动作——把左边传来的数,和上面传来的数相乘,再和之前累积的结果相加。
上方数据 ↓
┌─────┐
左方数据 →│ PE │→ 右方数据
└─────┘
下方数据 ↓
就这么简单。没有缓存预取、没有分支跳转、没有乱序执行。PE 是"一根筋"的单元,只认准"乘加"这一件事,所以它能被做得极小、极省电、极高频。
2.2 波浪式流动:泵血般的节奏
当成千上万个 PE 排成阵列,数据流动起来后,会出现一个非常美的现象:数据像波浪一样,一波一波地从阵列的一侧传到另一侧。
这背后是脉动阵列最核心的机制——“数据流驱动”:
- 每个时钟周期,所有 PE 同时做一次乘加;
- 做完之后,每个 PE 把输入的数据原样传给邻居(左边的传给右边、上面的传给下面);
- 下一个时钟周期,邻居接着算,数据继续往下一格流动。
于是你会看到:同一批数据,像潮水一样,一个节拍前进一格,穿过整个阵列。这个过程不需要任何中央控制单元去"指挥"每个 PE 什么时候算什么——节奏由时钟统一打拍,数据自己按路径走。
💡 一句话:脉动阵列里没有"调度",只有"节奏"。时钟是节拍器,数据是泵出的血液,PE 是沿途吸收养分的细胞。
2.3 一个 2×2 的迷你算例
为了让你真正"看到"波浪,我们用一个最小的 2×2 阵列,算一个 2×2 矩阵乘法。设权重矩阵 W 和激活矩阵 A 都是 2×2,我们只盯前两个时钟周期发生了什么。
假设权重第一行是 w11、w12,激活第一列是 a11、a21。它们分别从上方和左方进入阵列:
- 第 1 拍:左上角的 PE 收到 w11 和 a11,算出 w11×a11 存在肚子里;同时把 w11 往下传、a11 往右传。
- 第 2 拍:左上角 PE 收到从上方传来的 w12 和从左方传来的 a12,算出 w12×a12 累加进去;而它的左邻(第一行第二个 PE)收到 w12 和 a11,算出 w12×a11……
注意第 2 拍发生了什么:同一个 w12,在第 2 拍同时被两个 PE 使用——一个用它和 a12 相乘,一个用它和 a11 相乘。这就是"一次加载、多次复用"的最小样本。
💡 关键体会:数据不是"被送进某个 PE 锁起来",而是"穿过每个 PE 都留下一次乘加"。一个数据穿过整个阵列,就完成了一整列/一整行的乘积贡献。这就是波浪式流动的威力。
2.4 为什么"流动"比"调度"快
传统 CPU 每算一次,都要经历"取指令→解码→取数→计算→写回"五步,其中取数和写回要访问内存,延迟极高。更要命的是,CPU 的每个核心算完一个数,得等控制单元分配下一个任务,等待本身就是浪费。
脉动阵列则把"等待"彻底消灭了:
- 数据不需要反复从内存取:数据一旦进入阵列,就在 PE 之间流动,沿途被反复使用;
- 不需要等待指令:所有 PE 踩同一个节拍,该算的时候一定在算,不存在"等任务";
- 传输距离极短:数据只传给相邻 PE,走的是片内最短路径,延迟极低。
这三条叠加,让脉动阵列的"有效算力"(真正花在乘加上的时间占比)远超 CPU。CPU 可能有一半时间在等数据、等指令,而脉动阵列几乎每个时钟周期都在算。
如果用一个更贴近生活的类比:传统 CPU 像一个人边看菜谱边炒菜,炒一道菜要反复低头看菜谱(取指令)、去冰箱拿食材(取数)、再回锅前确认(写回);而脉动阵列像一条回转寿司传送带,食材在带上匀速前进,每个工位(PE)只负责往上面加一样配料,全程不需要任何人喊"下一步做什么"。传送带转一圈,成品就出来了——没有停顿,没有等待,没有无效动作。
三、权重与激活值的流动路线
上一节讲了"波浪式流动"的抽象概念,这一节把它落到具体的两个数据对象上:权重和激活值。
3.1 两类数据,两条固定的路
上一篇我们提过,矩阵乘法的两个输入是权重和激活值。在脉动阵列里,这两类数据走的是两条互相垂直的路:
- 权重:从顶部垂直向下流动(↓);
- 激活值:从左侧水平向右流动(→)。
也就是说,阵列的上方是权重入口,左方是激活值入口。权重一波波往下走,激活值一波波往右走,它们在每个 PE 里"相遇"一次,就完成一次乘加。
权重 权重 权重
↓ ↓ ↓
激活→ [PE] [PE] [PE]
激活→ [PE] [PE] [PE]
激活→ [PE] [PE] [PE]
3.2 相遇即计算,算完即传递
每个 PE 的标准动作,可以精确描述成三步:
- 接收:从上方的邻居接收一个权重值,从左方的邻居接收一个激活值;
- 乘加:把这两个值相乘,累加到 PE 内部保存的"部分和"里;
- 传递:把权重值原样传给下方邻居,把激活值原样传给右方邻居。
注意第 3 步的关键:PE 传出去的是"输入",不是"结果"。权重和激活值只是"路过"这个 PE,被它"借用"做了一次乘加,然后原封不动地继续往下、往右流。而乘加得到的"部分和",则暂时存在 PE 自己肚子里,等下一次同位置的乘加来累加。
3.3 部分和:另一条隐藏的流动路线
你可能想问:PE 算出来的部分和,最后怎么变成矩阵乘法的结果?
答案是:部分和也有自己的流动路线——它沿着"对角线"方向,从一个 PE 传到右下方或右下方的 PE,逐步累加。
一个矩阵乘法的结果单元 C[i][j],等于 A 的第 i 行和 B 的第 j 列逐项相乘再求和。在脉动阵列里,这个"逐项求和"不是在一个 PE 里一次做完的,而是让每一项的乘积,沿着对角线方向依次累加到一个 PE 上。等所有项都流过之后,这个 PE 肚子里的累加值,就是最终的 C[i][j]。
权重 ↓ 激活值 →
┌───┐ ┌───┐ ┌───┐
│PE │→部分和→│PE │→部分和→│PE │
└───┘ └───┘ └───┘
💡 记忆要点:权重垂直流、激活值水平流、部分和斜着累加。三条流动路线,构成了脉动阵列完整的"血液循环"。
继续用 2×2 的例子看部分和怎么"斜着"走。算 C[0][0] = w11×a11 + w12×a21:
- 第 1 拍,左上角 PE 算出 w11×a11,这是 C[0][0] 的第一项;
- 第 2 拍,w12 和 a21 都在阵列里流动,它们会在"第二行第二列"的 PE 相遇,算出 w12×a21;
- 这个 w12×a21 需要被"加"到第一项上,于是它沿着对角线方向,从右下方往回传递,最终累加到保存第一项的 PE 里。
你看,部分和走的是第三条路——斜着的路,它把散落在不同 PE 里的"乘积碎片"汇拢成一个完整的结果单元。这三条路线互不干扰、各司其职,才让整个阵列像一台精密的水车,每个齿轮都在正确的时间咬合。
3.4 时序:一切都是"踩点"的
脉动阵列能正确工作,依赖一个严格的约束:所有数据必须"对齐"到达。
也就是说,权重流到某个 PE 的同一时刻,激活值也必须正好流到这个 PE。早了或晚了,相乘的就是错误的两个数。为了做到这一点,设计者会在数据入口处故意插入"延迟"(比如让某些数据先走几个空 PE),确保两条路线在正确的位置、正确的时刻相遇。
这也是"脉动"这个词的深意:心脏泵血的关键不是血多快,而是每一次收缩都踩在同一个节拍上。脉动阵列同理,快不是唯一追求,"整齐"和"同步"才是正确性的前提。
四、数据复用:只加载一次,算多次
前面反复提到"数据在阵列里流动、反复使用"。这一节,我们把这件事彻底讲透——它是脉动阵列解决的核心瓶颈。
4.1 核心瓶颈:传输慢于计算
在芯片里,有一个残酷的事实:数据搬运的速度,远远跟不上计算的速度。
算一次乘加,可能只要零点几纳秒;但从内存(哪怕是 HBM)取一个数,延迟却是几十纳秒甚至上百纳秒。如果每算一次都要从外部取一次数,芯片 90% 以上的时间都在等数据,算力再强也白搭。
这就是所谓的"内存墙"(Memory Wall)——计算和存储之间的速度鸿沟,是过去几十年一直没被填平的核心瓶颈。
4.2 脉动阵列的解法:一次加载,多次复用
脉动阵列的绝招,就是让数据只从外部显存加载一次,然后在阵列内部被反复使用多次。
怎么做到?靠前面讲的"流动":
- 一个权重值进入阵列后,垂直往下流,沿途的每一行 PE 都会用到它——加载一次,被一列 PE 复用 N 次;
- 一个激活值进入阵列后,水平往右流,沿途的每一列 PE 都会用到它——加载一次,被一行 PE 复用 N 次。
也就是说,从外部搬进来一个数据,换来了阵列里 N 次乘加。这个 N 就是阵列的边长。阵列越大,N 越大,复用倍数越高,外部搬运的占比就越低。
4.3 对比:传统架构在"反复搬运"
传统架构(比如 CPU 或早期的 GPU)算矩阵乘法时,数据是反复进出内存的:
- 从内存取权重 A,算一次;
- 算完丢弃,下次要用再从内存取一次;
- 循环往复……
结果是:同一个数据,被反反复复地从内存搬到计算单元,搬了 N 次。每一次搬运都在消耗带宽和延迟,而真正用于计算的时间占比极低。
脉动阵列把这个过程完全反过来:数据搬进来一次,就在阵列里"转一圈",被沿途所有 PE 用完为止。搬运次数从"N 次"降到了"1 次"。
4.4 一个数量级的差距
用数字说话:假设一个 256×256 的矩阵乘法,传统架构需要把数据搬进搬出 256 次(每行每列都要反复取),而脉动阵列只需要搬 1 次,靠阵列内部的流动完成 256 次复用。
结论就是:相比传统架构,脉动阵列的数据传输开销降低了一个数量级以上。这不是"快一点点",而是从"搬运主导"变成了"计算主导"——瓶颈被整个掀掉了。
再用一个更直观的数字算账。假设我们要算一个 256×256×256 的矩阵乘法,涉及约 1678 万次乘加。如果采用"算一次搬一次"的传统方式,每做一次乘加都要从显存读两个数(一个权重、一个激活),总共要搬约 3355 万次数据。而脉动阵列把数据按行、按列"泵"进阵列后,每个权重沿垂直方向复用 256 次、每个激活沿水平方向复用 256 次,真正从显存搬进阵列的次数骤降到约 13 万次。
搬 3355 万次 vs 搬 13 万次——这就是一个数量级以上的差距。省下来的带宽和时间,全部转化成了有效算力。这也是为什么训练芯片的实测算力(有效 MAC 利用率)能大幅领先传统架构:它不是靠堆更高的峰值,而是靠把"搬运税"降到了最低。
💡 一句话总结:传统架构是"算一次搬一次",脉动阵列是"搬一次算一列/一行"。复用倍数,就是性能的倍数。
五、为什么它碾压传统架构
到这里,我们已经把脉动阵列的原理讲透了。最后一章,做一个系统的对比,看清它到底"碾压"在哪里,以及它有没有代价。
5.1 三个维度的碾压
第一,数据传输开销。 这是最核心的优势。脉动阵列靠数据复用,把外部搬运次数降了一个数量级以上,直接掀掉了内存墙。传统架构再优化缓存,也做不到"搬一次算一列"的程度。
第二,控制开销。 传统 CPU 要取指令、解码、分支预测、乱序执行,这些"控制"开销消耗了大量晶体管和功耗。脉动阵列几乎不需要这些——数据流本身就是指令,时钟就是调度。省下来的晶体管,全部投给了计算单元。
第三,算力密度。 因为 PE 简单、规则、没有冗余控制逻辑,同样面积的硅片,脉动阵列能塞进多得多的计算单元。算力密度(单位面积的有效算力)比传统架构高一个数量级,这也是训练芯片能把功耗和面积都用在刀刃上的根本原因。
5.2 它也有代价:不灵活
世界上没有免费的午餐。脉动阵列的代价,就是它只擅长规整的、可预测的计算。
矩阵乘法是规整的——数据形状固定、流动路线固定、每个 PE 的动作固定。但现实中的计算不全是矩阵乘法:动态形状、稀疏数据、条件分支、不规则内存访问,都会让"固定路线"失效。
遇到这些场景,脉动阵列就尴尬了:
- 动态形状:数据维度每次都不一样,阵列的流动路线和延迟设计是固定的,对不上号;
- 稀疏数据:很多数据是 0,脉动阵列却还是"一个不落"地流过每个 PE,浪费算力;
- 不规则访问:数据不是规整张量时,找不到固定的流动路径。
这也是为什么现在的训练芯片,不会只有脉动阵列一种引擎——往往同时配备通用计算单元(如 CUDA Core)来处理那些"不规整"的部分,脉动阵列专心负责矩阵乘加。
💡 效率技巧:理解脉动阵列,要记住它的**“适用边界”**——它是矩阵乘加的王者,但不是万能的通用引擎。评价一颗训练芯片,要看它"脉动阵列 + 通用单元"的搭配是否合理,而不是只看峰值算力。
针对动态形状,业界有两类常用补救手段。第一类是"静态化":把动态图编译成静态图(如 TensorFlow 的 XLA、PyTorch 的 TorchScript),在编译期就把张量形状固定下来,让脉动阵列能按固定路线高效执行。第二类是"异构分流":把规整的矩阵乘交给脉动阵列,把不规则算子(如 Gather、Scatter、动态掩码)交给通用计算单元,两者并行,各干各的擅长活。
针对稀疏数据,也有专门的解法——稀疏脉动阵列。它在 PE 之间加入了"跳过零"的机制:遇到权重为零时,对应 PE 直接跳过,不浪费一个时钟周期。英伟达的 2:4 结构化稀疏、谷歌 TPU 对稀疏矩阵的支持,本质都是在给脉动阵列"补上处理稀疏的能力"。这些手段说明:脉动阵列不是一成不变的,它一直在进化,往"更灵活"的方向长。
5.3 一个精妙的工程权衡
最后想说的是,脉动阵列的本质,是一个极其精妙的工程权衡:
- 它牺牲了灵活性(只能做规整计算),换来了极致的效率和密度;
- 它牺牲了通用性(不管分支、不跑操作系统),换来了数据传输开销的断崖式下降。
在 AI 计算这个特定战场上,这个权衡是极度划算的——因为 AI 计算 90% 以上的时间,就是矩阵乘加。用"不灵活"换"极致快",正是专用硬件战胜通用硬件的底层逻辑,也是上一篇"场景化重构"最生动的注脚。
配图
图 1:脉动阵列 PE 二维阵列与数据波浪式流动图
flowchart LR
W[权重输入 顶部] -->|垂直向下流动| PE1[PE]
W --> PE2[PE]
A[激活值输入 左侧] -->|水平向右流动| PE1
A --> PE3[PE]
PE1 -->|部分和 斜向累加| PE4[PE]
PE2 --> PE4
PE3 --> PE4
PE4 -->|输出 Cij| OUT[结果输出]
权重自上而下、激活值自左而右,在每个 PE 中相遇做一次乘加;部分和沿对角线方向逐步累加,最终从阵列一角输出矩阵乘法的结果。
图 2:传统架构反复搬运 vs 脉动阵列一次加载多次复用
flowchart TB
subgraph 传统[传统架构:算一次搬一次]
M1[内存] -->|取权重| C1[计算单元]
C1 -->|算完丢弃| M1
M1 -->|再取权重| C1
end
subgraph 脉动[脉动阵列:搬一次算多次]
M2[内存] -->|只搬一次| ARR[PE 阵列]
ARR -->|数据内部流动 复用N次| ARR
ARR -->|输出结果| R[结果]
end
左图:传统架构里,同一个数据被反复从内存搬进搬出;右图:脉动阵列只搬一次,数据在阵列内部流动、被 N 个 PE 反复复用,外部搬运开销降低一个数量级以上。
写在最后
脉动阵列,是训练芯片"算得快"的真正秘密。它用规则排列的 PE 阵列、波浪式的数据流动、一次加载多次复用的机制,把数据传输开销降了一个数量级,掀掉了传统架构最头疼的内存墙。它的不灵活,恰恰是它极致高效的代价——在"矩阵乘加主导一切"的 AI 世界里,这笔交易无比划算。
理解了脉动阵列,你就理解了 AI 芯片为什么和 CPU 是"两种生物"。下一篇,我们回到训练芯片的整体,看看 2025-2026 年它的制程、显存、互联"肌肉量"到底发展到了什么程度。
【思考题】
脉动阵列适合规整的矩阵运算,遇到动态形状或不规则计算会低效吗?怎么解决?欢迎讨论。(提示:想想通用单元辅助、算子融合、静态图编译这些手段能不能补救。)
【系列文章预告】
下一篇看训练芯片的"肌肉量"——2025-2026 年它的制程、显存、互联现状。
标签:脉动阵列、Systolic Array、PE处理单元、数据复用、训练芯片、矩阵乘法、硬件原理
核心算力支撑为脉动阵列(Systolic Array)架构,区别于通用芯片;规则排列的 PE 处理单元阵列,每个 PE 独立执行 MAC;权重从顶部垂直向下、激活值从左侧水平向右波浪式流动;每个 PE 接收两类数据后同步乘加,结果传给相邻 PE;数据只从外部显存加载一次、阵列内多次复用,解决传输慢于计算的核心瓶颈;相比传统架构,数据传输开销降低一个数量级以上。
更多推荐



所有评论(0)