用sysview优化npu固件调度的方法

一、npu固件调度的监控方法

NPU的调度如何去优化,一般场景下聊的是上层调度的策略,比如如何规避权重搬运带宽墙,如何拆分计算图等等。

而实际上,NPU固件层的调度效率这个底层的核心瓶颈也很重要,任务下发到流以后,固件内部能否快速高效地执行很关键,固件是直接掌管硬件资源的,这些资源就包括:npu core、dma引擎等等,这些资源是否空闲,固件能直接"看"得见。

比如说,一个3核的npu,固件会不会把任务自动分发到空闲的核心,不要经常出现core0跑满100%, 而core1、core2完全闲置的情况。

原则是,尽量让Npu的core核心有事情可做,不要空转。

那么如何监控这种性能瓶颈就变得很重要了------Npu固件是一个跑在NPU内部微控制器上的实时程序,一般会跑一个简单的RTOS操作系统,那么就存在中断响应、任务切换、资源等待等等行为,那么是否有一个工具可以可视化地监控这些行为呢?答案是有的,笔者推荐一款工具,就是segger提供的sysview这个工具。

SEGGER SystemView‌ 是一款面向嵌入式系统的实时运行行为记录与可视化分析工具,由SEGGER官方推出,能深度还原系统真实运行状态,解决传统断点调试无法捕捉的多线程、中断交互类问题。

核心功能

  1. ‌可视化调度时间线‌:以图形化方式完整展示所有任务、中断、软件定时器的执行顺序,精确到微秒级时间戳,直观呈现谁占用了CPU、谁被抢占、谁在等待资源。
  2. ‌系统性能统计‌:自动生成CPU负载分布、各任务执行时长占比、中断触发频率等统计数据,帮你快速定位系统性能瓶颈,评估峰值负载下的硬件余量。
  3. ‌深度事件追溯‌:完整记录信号量获取/释放、队列读写、任务挂起/恢复等所有RTOS内核事件,精准还原多任务间的交互细节,定位资源冲突、优先级翻转等隐蔽问题。
  4. ‌离线回放存档‌:支持将完整的事件记录保存为.svdat文件,后续可随时离线回溯分析,也能作为系统性能文档存档,方便对比优化前后的效果。

典型应用场景

  • 排查偶发系统卡顿、任务饿死、中断响应超时等传统调试手段难以定位的问题。
  • 验证实时系统硬实时性指标,测量从中断触发到ISR实际执行的延迟,找到拖慢响应的长临界区。
  • 评估系统CPU负载余量,在新增功能前确认硬件资源是否足够支撑,辅助硬件选型决策。
  • 优化NPU、MCU等嵌入式固件的调度逻辑,像之前我们聊到的NPU固件调度优化,它就是核心分析工具。

基础运行架构

一套完整的SystemView链路由三部分组成:

  1. 目标端:将SEGGER_SYSVIEW库代码编译进固件,在系统事件发生时自动写入带时间戳的记录到RAM缓冲区。
  2. 传输层:通过J-Link的RTT通道(最常用)、UART等方式,把缓冲区数据实时上传到PC。
  3. PC端上位机:接收数据后解析、渲染成可视化时间线和统计报表,供开发者分析。

二、如何移植

移植sysview是需要花费一些功夫的,不过原理上不难,首先需要去segger官网下载最新版本的代码,然后把segger_sysview.c,segger_rtt.c等代码拷贝到工程就可以了。

然后,我们需要理清楚我们关心的观测点是啥:

  • 任务调度与上下文切换追踪 (这里的任务不是指的npu的任务,而是rtos的task)

  • 中断进入/退出与 ISR 时间统计

  • 门铃(doorbell)/DMA/围栏(fence)/kernel launch等自定义事件,这个就是我们最关心的npu任务执行的部分

  • Mailbox等host和固件通信的 IPC 延迟分析

2.1 操作系统部分

首先针对前两点,任务调度和中断进出部分,sysview的官方代码已经包含了主流操作系统的钩子函数,只需要把segger_sysview_freertos.c拷贝到我们的工程里就可以了。然后,对freertos进行一个配置,主要在freertosconfig.h对一些宏进行打开或者关闭,这里有一些微调的部分,比如说,进入idle task非常频繁,而对此我们并不关心,所以在这里对task的name做一个删选,如果是Idle task进出,就不要产生打印了。

然后,进出中断也是比较频繁的行为,我们并不关心,可以关闭:

2.2 自定义部分

Marker是sysview里比较适合来观测某些事件的持续时间的方法,使用的时候是定义一些自己关心的一些事件,在在初始化的时候,用SEGGER_SYSVIEW_NameMarker做一个声明。

比如,在本例,我们针对doorbell、dma、kernel launch、ipc等消息,我们设置了如下这些namemarker:

然后比如我们要监控kernel launch从开始到结束的整个时间,那么在开始的时候,调用SEGGER_SYSVIEW_MarkStart

在结束的时候,调用SEGGER_SYSVIEW_MarkStop

最后生成的效果就是这样的

三、实战案例

3.1 某次graph kernel测试用例不过

一个简单的case:一个job,包含了三个简单的command buffer,一个是h2d的memcpy的dma命令,一个是kernel launch的命令,一个是d2h的memcpy的dma命令,这个job下发到固件的流以后,由固件执行完返回host,但是host读取返回结果的时候发现与预期不符。

抓取sysview时序以后,很容易就可以分析到问题所在:

从上图可以看到,job done作为固件返回host的一条ipc消息,其发送的时间点过早,(期待中的时间点是三个command buffer都执行完毕才能发送),导致host去读内存中的数据的时候,由于d2h的memcpy还没有完成,数据是不对的。

修改代码中的bug后,再次抓取sysview,看到正确的时序,可以清晰地看到一次包含了两个dma copy和一个kernel launch的job的生命周期::

3.2 kernel launch中断支持

在kernel launch没有支持中断以前,我们的固件是在monitor task中检查完成情况的,所以每次kernel launch都会调度出doorbell task,在以1ms为节拍的monitor task检查到kernel launch完成后,才会继续下一个kernel launch,效率低下,如下图,一个包含8个kernel launch的job就会消耗大概8ms的时间:

而支持了中断以后,一个包含了8个kernel launch的job,总的时间才330us。原因是不再需要调度到monitor task,而由中断直接去唤醒doorbell task的信号量就可以了,这样就很快了。

PS:以上案例只是举个例子,各家NPU的固件代码不是开源的,实现方式也是前差万别,因为固件和你的硬件以及mcu是强相关的,所以会有很大的不同。但是,用sysview这种工具作为分析手段的方法,应该是很有效的。

相关推荐
Industio_触觉智能4 天前
瑞芯微AI算力NPU路线图与协处理器|触觉智能瑞芯微RK方案商出品
人工智能·嵌入式硬件·硬件架构·智能硬件·npu·瑞芯微·端侧ai
Java后端的Ai之路9 天前
昇腾NPU显存管理避坑指南:从npu-smi输出精准识别空闲卡的底层逻辑与实战
服务器·网络·数据库·npu·大模型服务
zhangfeng113316 天前
Ag / Cu / Au / Ru / Ir / Rh银 铜 金 钌铱 铑 纳米尺度下的 导电性 + 扩散/迁移缺点
人工智能·华为·ai编程·npu
zhangfeng113317 天前
Reward Hacking 奖励钻空子 / 奖励作弊 Specification Gaming(规范博弈)
人工智能·华为·ai编程·npu
zhangfeng113318 天前
国产GPU/AI算力芯片现状(修订完整版 · 截至2026年9月
人工智能·算法·ai编程·npu
熊猫钓鱼>_>20 天前
Harmony Intelligence AI 开放能力深度解读 | 图像超分 + 文搜图:端侧视觉的“放大镜“与“搜索引擎“
人工智能·搜索引擎·harmonyos·鸿蒙·npu·图像超分·文搜图
zhangfeng113320 天前
qjlDim 含义 TurboQuant QJL Quantized Johnson-Lindenstrauss,量化JL随机投影
人工智能·算法·ai编程·npu
zhangfeng11331 个月前
Ubuntu 版的 CANN 9.2.0-beta.1 的下载方式 三大云厂商的服务器系统
人工智能·华为·ai编程·npu·cann