024、NPU指令集架构(ISA)概述:从CISC到VLIW
去年冬天调试一块国产NPU芯片的卷积算子,跑ResNet-50前向推理,死活比理论算力低了一个数量级。抓了三天波形,最后发现是指令发射槽的冲突——两条MAC指令争同一个数据总线,硬件自动插入三个空泡周期。那一刻我盯着逻辑分析仪上的气泡,突然理解了为什么NPU的ISA设计比CPU更“拧巴”。
从一条“死掉的”CISC指令说起
当年做DSP时,一条乘累加指令MAC R0, R1, R2能同时完成乘法、加法、地址自增、循环计数。看起来很美好对吧?但当你把这条指令塞进NPU的流水线,问题就来了:NPU的乘累加单元通常有几十甚至几百个PE(处理单元),每个PE都要独立取指、译码、执行。如果每条指令都像CISC那样隐含多个微操作,译码器的面积会爆炸——一个32核的NPU,译码逻辑能吃掉芯片面积的15%以上。
更致命的是,CISC的变长指令让NPU的取指单元无法预判下一条指令的边界。NPU的取指带宽动辄512位甚至1024位,如果指令长度不固定,取指缓冲区的设计会变成噩梦。我见过一个团队为了兼容变长指令,在取指阶段插了三级FIFO,结果延迟从1周期变成5周期,直接废掉了实时推理的硬实时特性。
RISC的“瘦身”与NPU的“不满足”
RISC把指令长度固定为32位,每条指令只做一件事。这在CPU上很成功,但放到NPU里,你会发现一个尴尬的事实:NPU的核心操作是矩阵乘法和卷积,这些操作天然需要多个数据源和多个目的地址。一条RISC风格的