052、NPU的矩阵乘法单元:专用硬件加速去年调试一块自研NPU芯片时,遇到一个诡异现象:跑ResNet-50前向推理,前几层延迟正常,到第7层卷积突然卡了将近3毫秒。用逻辑分析仪抓总线,发现矩阵乘法单元(MAC阵列)在那一层频繁进入“忙等待”状态——数据已经喂进去了,但结果迟迟不出来。翻看设计文档,发现这层卷积的输入通道数是256,输出通道数是384,而我们的MAC阵列是16×16的脉动阵列。问题出在:当矩阵维度不是MAC阵列尺寸的整数倍时,硬件自动做了补零填充,但补零操作触发了数据预取器的边界条件bug,导致流水线断流。这个坑让我意识到:NPU的矩阵乘法单元远不是“一堆乘法器堆在一起”那么简单。今天就从硬件架构和软件适配两个角度,拆解这个专用加速器的设计哲学。矩阵乘法单元的本质:不是“算得快”,而是“喂得快”很多人以为NPU加速矩阵乘法的秘诀是堆乘法器——比如一个时钟周期算256个乘加。这没错,但只对了一半。真正决定性能的是数据供给速度。一个MAC(乘加单元)每个时钟周期需要两个操作数和一个累加值,如果数据从DRAM搬过来,延迟动辄几十纳秒,MAC就得干等。所以NPU的矩阵乘法单元核心设计目标只有一个:让MAC阵列永远有活干。常见的实现方式是脉动阵列(Systolic Array)。Google TPU v1用的就是256×256的脉动阵列,每个周期能完成65536次乘加。它的工作方式像流水线工厂:权重数据从左边流入,输入特征图从上方流入,部分和在对角线方向累加。这种结构的好处是数据复用率极高——
052、NPU的矩阵乘法单元:专用硬件加速
052、NPU的矩阵乘法单元:专用硬件加速去年调试一块自研NPU芯片时,遇到一个诡异现象:跑ResNet-50前向推理,前几层延迟正常,到第7层卷积突然卡了将近3毫秒。用逻辑分析仪抓总线,发现矩阵乘法单元(MAC阵列)在那一层频繁进入“忙等待”状态——数据已经喂进去了,但结果迟迟不出来。翻看设计文档,发现这层卷积的输入通道数是256,输出通道数是384,而我们的MAC阵列是16×16的脉动阵列。问题出在:当矩阵维度不是MAC阵列尺寸的整数倍时,硬件自动做了补零填充,但补零操作触发了数据预取器的边界条件bug,导致流水线断流。这个坑让我意识到:NPU的矩阵乘法单元远不是“一堆乘法器堆在一起”那么简单。今天就从硬件架构和软件适配两个角度,拆解这个专用加速器的设计哲学。矩阵乘法单元的本质:不是“算得快”,而是“喂得快”很多人以为NPU加速矩阵乘法的秘诀是堆乘法器——比如一个时钟周期算256个乘加。这没错,但只对了一半。真正决定性能的是数据供给速度。一个MAC(乘加单元)每个时钟周期需要两个操作数和一个累加值,如果数据从DRAM搬过来,延迟动辄几十纳秒,MAC就得干等。所以NPU的矩阵乘法单元核心设计目标只有一个:让MAC阵列永远有活干。常见的实现方式是脉动阵列(Systolic Array)。Google TPU v1用的就是256×256的脉动阵列,每个周期能完成65536次乘加。它的工作方式像流水线工厂:权重数据从左边流入,输入特征图从上方流入,部分和在对角线方向累加。这种结构的好处是数据复用率极高——