
你买了一张RTX 5090,知道它有100万亿次浮点运算/秒的算力。但你想过没有:这块芯片里面到底在发生什么?那些晶体管是如何组织起来,最终跑出一个矩阵乘法的?
著名硬核播客博主Dwarkesh Patel最近邀请到了MatX CEO、前谷歌TPU架构师Reiner Pope,在黑板上从零开始,用最原始的逻辑门,一步步搭出了一块AI芯片。
这篇文章,我们就跟着Reiner的粉笔,看看一块芯片的「内心世界」。
文字稿链接:
https://www.dwarkesh.com/p/reiner-pope-2
原视频自行搜索:
Why do GPUs, TPUs, & the human brain look the way they do? – Reiner Pope

一切从与门开始
芯片最底层的原语,是逻辑门:与门(AND)、或门(OR)、非门(NOT)。它们通过金属导线连接在一起。
AI芯片的核心任务,是矩阵乘法。而矩阵乘法内部最基本的操作,叫「乘加运算」(multiply-accumulate),也就是把两个数相乘,再加到累加器里。
为什么乘加是天然的原语?看看矩阵乘法的伪代码就明白了:output[i,k] += input[i,j] × other[j,k]。每一步循环都在做乘加。而且AI芯片还有一个特点:乘法用的是低精度(比如FP4),累加需要更高精度(比如FP8),因为误差会在累加过程中累积。
Reiner用了一个4比特乘4比特的例子,在黑板上手算了一遍。
听起来简单?算一下代价:要产生所有部分积,需要p×q个与门(4比特乘4比特就是16个)。但这些与门只是开胃菜,真正的功夫在求和。
一位一位地消灭比特
求和的工具,叫「全加器」。你可能会以为全加器是加32位数的,但在芯片层面,它只加三个单比特数:输入三个比特,输出两个比特(因为0+1+1=2,二进制就是10)。它也被称为3→2压缩器,把三比特信息压缩成两比特。
背后的直觉很简单:全加器就是「数这一列里有多少个1,然后用二进制表示出来」。
Reiner在黑板上演示了一种叫「Dadda乘法器」的算法:把所有需要加的比特排成网格,然后用全加器不断从每一列取出三个比特,输出两个比特,反复操作,直到最后只剩下一个数。
那么,一个4比特乘4比特的乘加运算需要多少个全加器?
答案是p×q个,也就是16个。公式很简洁:输入有p×q + (p+q)个比特,输出有p+q个比特,每用一个全加器消灭一个比特,所以需要p×q个。
这揭示了一个关键规律:乘法器的面积和比特位宽是平方关系。所以精度减半,理论上算力应该增加4倍。NVIDIA在B300及之后的芯片规格中已经开始承认这一点——FP4性能是FP8的3倍(理论上应该是4倍)。
你感受不到的「数据搬运税」
到这里,乘法器本身看起来挺大。但真正的震撼在后面。
Reiner把视角拉远:在一个传统的CUDA核心或CPU核心里,乘法器旁边是一个寄存器堆(register file),存放着一些操作数。要进行乘加,需要从寄存器堆里随机读取三个数,送给乘法器,再把结果写回。
怎么「随机读取」?靠一个叫「多路选择器」(mux)的电路。
一个n路mux(比如从8个寄存器中选一个),每个寄存器存p比特数据,需要n×p个与门加上(n-1)×p个或门。
算一下账:假设寄存器堆有8个条目,每个4比特,读取三个操作数需要3×8×4 = 96个与门。而乘加器本身只需要p×q = 16个与门(这里p=4, q=4)。
光是搬运数据的电路,就是计算电路的好几倍。
这还只是最小的寄存器堆。Reiner说,在这个设计里,大约7/8的成本花在了数据的读写上,只有1/8花在真正的计算上。
这就是芯片设计最核心的矛盾:你关心的计算,占的面积其实很小;你不关心的数据搬运,却花了最多的面积。
脉动阵列:一次改变游戏规则的「升维」
在Volta架构之前,NVIDIA GPU的CUDA核心就是上面这个样子:大部分面积被数据搬运吃掉。Tensor Core的出现改变了这一切,而它背后的核心思想,叫「脉动阵列」(systolic array)。
怎么解决数据搬运太贵的问题?思路很巧妙:往上走一层循环。
之前,我们把「一次乘加」固化到硬件里。现在,我们把「一整段矩阵乘法循环」固化到硬件里。
关键优化有两个。第一,让单位数据搬运能做更多的计算。第二,利用矩阵乘法的一个特性:权重矩阵可以长期保持不变。
具体做法是:把权重矩阵直接存储在脉动阵列里面,不来回搬。输入向量从左到右流入,每一列做一次点积,结果从底部流出。权重存在本地寄存器里,被反复使用,不需要每次从寄存器堆重新加载。
但权重矩阵一开始是怎么装进去的?答案是「慢慢灌」。用菊花链的方式,一个时钟周期加载一行,花y个时钟周期把整个矩阵装好。因为权重会停留很长时间,所以加载慢一点没关系。关键是加载的带宽(决定了面积)被控制在了O(x),而不是O(xy)。
这是一个贯穿全栈的主题:在芯片设计的每一个层级,从逻辑门到数据中心,都在做同一件事——最大化计算相对于通信的比例。
脉动阵列是目前已知最高效的矩阵乘法电路。老TPU里的脉动阵列是128×128的规模。
时钟周期:芯片的「心跳」
一块芯片有1000亿个晶体管在并行工作。它们如何同步?不是靠软件里的互斥锁,而是靠一个全局时钟信号。大约每纳秒一次,芯片上所有电路暂停、对齐、然后同时迈出下一步。
这就是时钟周期。
时钟周期的瓶颈在哪?在两个寄存器之间的「逻辑云」的延迟。如果这段逻辑太复杂,信号在下一次时钟脉冲到来之前来不及稳定,就会出错。芯片设计师会留出裕量,确保在25%的时钟周期内就能完成,概率上几乎不可能错过。
但问题来了:如果把逻辑云劈成两半,中间插一个寄存器(叫流水线寄存器),时钟频率就能翻倍。代价呢?多了存储面积。
更棘手的是有「反馈回路」的情况。比如一个累加器,每周期加一个数。如果你在加法器中间插寄存器,它就不再是连续求和了,而是变成两个独立的求和(偶数项的和、奇数项的和)。这种「回路」是所有芯片都会遇到的硬约束,也是决定时钟周期的最终因素。
有趣的是,如果把时钟推得极高,比如用一个寄存器配一个与门,理论上能跑到五六GHz以上。但这样做的结果是:几乎所有面积都被同步寄存器吃掉,根本没地方做真正的计算。高时钟频率意味着低吞吐量,因为吞吐量 = 每周期能做的计算 × 时钟频率。这和之前聊过的推理批次大小是一个道理:小批次让单个用户延迟低,但总吞吐量反而下降。
FPGA 和 ASIC:什么时候用哪个
FPGA和ASIC用的是同一套概念模型:逻辑门加连线,在固定时钟周期下工作。理论上,ASIC上能跑的东西FPGA上也能跑。
但两者的成本结构完全不同。第一片FPGA花你一万美元,而第一片ASIC花你3000万美元——因为需要完整的流片(tape-out)。所以FPGA适合那些需要确定性延迟、高并行度、但工作负载经常变化的场景(比如Jane Street的高频交易 )
不过,一旦进入大规模量产,ASIC的单片成本远低于FPGA。更重要的是,实现同样的逻辑功能,FPGA消耗的硅面积是ASIC的约10倍,能效也比ASIC差一个数量级。
FPGA是怎么做到「可编程」的?核心在于三个组件:寄存器、查找表(LUT)、以及满天星斗般的多路选择器。
每一个查找表前面都有一个mux,从周围的寄存器和LUT中选择输入。FPGA的「编程」,本质上就是配置所有这些mux的控制位——告诉每个mux它应该从哪个邻居取数据。
查找表本身也很巧妙:它本质上是一个4输入1输出的真值表,存储了16个配置比特。你想让它变成与门,就写入与门的真值表;想要或门,就写入或门的真值表。
但代价是什么?一个4输入查找表,用mux实现的话需要大约32个门(16个与门+16个或门)。而如果直接在ASIC上做一个四路与门,只需要3个与门。
同样的功能,FPGA用了10倍的门。这就是同等逻辑下FPGA面积和功耗比ASIC差一个数量级的直接来源
Cache vs 暂存器:确定性从哪来?
CPU的非确定性延迟,最大的来源是缓存。CPU有一个缓存系统,自动记住最近访问过的DDR内存数据。当你执行访存指令时,硬件自动判断数据在缓存里还是需要从DDR取。缓存比DDR快两个数量级,没有缓存几乎所有程序都会慢100倍。
但数据是否命中缓存,取决于CPU的环境:别的程序在干嘛,最近跑过什么,缓存替换算法的随机性。这就是CPU延迟不确定的根本原因。
AI芯片(像TPU)换了一种设计哲学,叫「暂存器」(scratchpad)。它不用硬件自动判断数据在哪,而是给软件两种不同的指令:一种访问片上暂存器,一种访问片外HBM。把「数据在哪」的决定权从硬件交还给软件。
这也是为什么Groq和TPU可以宣称自己有确定性延迟——它们用scratchpad而不是cache。
CPU、GPU、TPU:核心大小的差异
为什么 CPU 只有几十个核,GPU 有几千个,而 FPGA 有几百万个 LUT?
关键在于每个核有多大。
FPGA 的 LUT 只有 16 个门,所以可以在芯片上堆很多。
CPU 的核之所以大,主要是两个原因:
一是缓存(cache)。CPU 缓存比主存(DDR)快 100 倍,对于通用程序来说几乎是必须的——否则程序会慢 100 倍。但缓存本身占据了大量面积。
二是分支预测器(branch predictor)。当 CPU 遇到条件分支时,完整执行一个分支判断需要 5 纳秒,但 CPU 希望以 1-2 GHz 的频率运行,等不起。分支预测器提前 5 个时钟周期预测分支走向,让 CPU 不用停下来等。
把这两个组件去掉,或者大幅缩小,就是 GPU 核(SM)相对 CPU 核更小的主要原因。GPU 核不需要复杂的分支预测,因为 GPU 是大规模并行、同构计算的场景,控制流简单。
TPU 和 CPU 的另一个重要区别是内存系统的设计哲学:
CPU 用缓存,硬件自动决定数据是从缓存还是主存读取,这引入了不确定性。
TPU 用 scratchpad(暂存器),软件显式决定数据从哪里读取:一类指令访问 scratchpad,另一类访问 HBM。这让延迟变得可预测,但需要软件工程师更仔细地管理内存。
大脑 vs 芯片
一个常见的对比:大脑和芯片有什么区别?
第一个区别是稀疏性。芯片可以做结构化稀疏(比如整列剪枝),但大脑是非结构化稀疏——任何神经元可以连接任何其他神经元,没有对齐的列结构。
第二个区别是时钟频率。大脑的「时钟周期」比芯片慢得多。这在一定程度上是为了节能:频率越高,需要的电压越高。但Reiner指出,如果只是把GPU从1GHz降到1MHz,它不会获得1000倍的能效提升。因为芯片的大部分能耗来自于比特翻转(0变1、1变0),跑得慢只是翻转次数少,不等于能效高。它会很快完成计算,然后长时间闲置,闲置期间不耗什么电。
第三个区别是批次大小。GPU跑推理时批次是1000,而大脑只有一个你。从这个角度看,如果让GPU以1MHz的频率、批次为1的方式运行,确实会更接近大脑的工作方式。
GPU就是一堆小TPU
最后,Reiner给出了一个令人印象深刻的高度概括:从顶层架构看,GPU就是一堆小的TPU平铺在整个芯片上。

具体来说,GPU由很多近乎相同的SM(流式多处理器)组成,排列成规则的网格,中间是L2缓存。而TPU只有几个粗粒度的矩阵单元(MXU),中间夹着一个向量单元。
把TPU缩小——矩阵单元变小,向量单元变小——你就得到了一个SM。SM里的Tensor Core本质上就是一个小的脉动阵列。
这两种设计各有取舍。TPU的粗粒度设计让单个脉动阵列更大,更好地摊销了寄存器堆的成本。但代价是向量单元和矩阵单元之间的数据传输只能走两条边界的路径。GPU里有16条这样的路径,数据搬运的灵活性更高。
这就是MatX正在尝试做的事:既要有GPU那样被SRAM包围的小型脉动阵列的灵活性,又要丢掉SM里为支持CUDA架构而存在的大量占用面积的东西。Reiner公开提到过一种叫「可拆分脉动阵列」的设计——本质上是一个大阵列,但可以按需变成多个小阵列。
从与门到脉动阵列,从时钟周期到分支预测,芯片的世界是一个层层叠叠、处处权衡的世界。而所有权衡的核心,始终指向同一个问题:如何让计算跑赢通信。
--end--
最后记得⭐️我,每天都在更新:如果觉得文章还不错的话可以点赞转发推荐评论
/...@作者:你说的完全正确(YAR师)







