160、NPU的编译器开发:内核融合与循环分块 嵌入式NPU原理基础:NPU的编译器开发——内核融合与循环分块从一次诡异的性能回退说起去年夏天,我在调试一款自研NPU的ResNet-50推理时,遇到了一个让我连续加班三天的bug。模型在仿真器上跑得好好的,一上FPGA实测,某些层的延迟反而比单层跑还慢。更诡异的是,同样的算子组合,换一个输入尺寸,性能又正常了。我盯着波形图看了两个小时,最后发现是编译器在做内核融合时,把两个本不该合并的卷积层强行拼在了一起。融合后的中间结果尺寸超过了片上SRAM的容量,导致数据反复在DDR和NPU之间搬运——这就是典型的“融合负优化”。这个教训让我意识到:NPU编译器不是简单的“把算子拼起来”,它需要在计算密度、数据复用、存储层次之间做精密的权衡。今天这篇笔记,就聊聊内核融合和循环分块这两个编译器核心优化技术,以及我在实际开发中踩过的坑。内核融合:不是所有邻居都该住在一起融合的本质是减少“中间人”NPU的典型执行流程是:从DDR读数据→计算→写回DDR→下一个算子再读。每一次DDR访问都是昂贵的,功耗和延迟都远高于片上访问。内核融合的核心思想,就是把多个算子的计算合并成一个“大算子”,让中间结果留在片上寄存器或SRAM中,避免反复进出DDR。听起来很美好,但实际做起来全是细节。以最常见的“卷积+ReLU+池化”融合为例:// 不融合:三个算子各自为政