第七周周报(8.9-8.15)
本周工作主要集中在 K3 官方 Runtime 调度行为的黑盒实验、PMU 观测基础,以及 USB 驱动的 DMA/cache 一致性问题上。AI Runtime 方面暂时不直接修改 Scheduler,而是先在 K3 Ubuntu 环境下使用官方 ONNX Runtime + SpaceMIT Execution Provider 跑真实推理,通过 E0-E3 对照实验观察 Runtime 对外部负载和内部任务状态的响应;USB 方面则继续解决上一周遗留的枚举问题,最终通过 Svpbmt 处理控制器频繁访问的 DMA ring 和相关结构体,使上层 crabusb 链路跑通。
本周工作概览
本周主要完成和推进了三项工作:
- 在 K3 Ubuntu 上使用
onnxruntime_perf_test、SpaceMIT Execution Provider 和量化 YOLOv8n 模型搭建 Runtime 黑盒调度实验,按 E0-E3 四组场景区分 Runtime 内部负载和 Runtime 外部硬件负载。 - 使用 Linux
perf对 CPU8-15 的instructions/cycles做周期采样,并整理 K3 PMU Raw Event 的使用和映射,形成 K3 RawPerfEvent 映射文档。 - 修复 K3 USB 驱动的 DMA/cache 一致性问题。对 USB 控制器会频繁读写的 ring 区和相关 DMA 常驻结构使用 Svpbmt 提供合适的内存属性,修复此前控制器和 CPU 看到的数据不一致问题;修复后上层
crabusb已可以正常继续枚举和传输流程。
K3 Runtime 黑盒调度实验
目前 K3 官方 Runtime 的具体 Scheduler 实现仍然不完全透明,因此本周先不假设它内部究竟使用了队列长度、CPU 利用率还是其他指标,而是从外部构造不同负载组合,观察 Runtime 最终把推理工作放到哪些核,以及对应的吞吐和延迟如何变化。
测试环境使用 K3 Ubuntu,推理侧使用官方 ONNX Runtime 的 SpaceMIT Execution Provider,模型为量化后的 YOLOv8n:
onnxruntime_perf_test
yolov8n_no_dfl.q.onnx
-e spacemit
SPACEMIT_EP_INTRA_THREAD_NUM=1
SPACEMIT_EP_INTER_THREAD_NUM=1
同时使用 perf stat -I 对 CPU8-15 周期采样 instructions 和 cycles,把 Runtime 的实际执行位置和外部负载放在同一条时间线上观察。
E0-E3 实验设计
| 编号 | 实验场景 | Runtime 内部负载 | 外部硬件负载 | 主要观察点 |
|---|---|---|---|---|
| E0 | Baseline:只运行单个 ONNX 推理任务 | 低 | 低 | 记录无干扰时的默认执行位置、吞吐和延迟 |
| E1 | External hog:Runtime 外单独启动负载,并逐核移动 | 低 | 高 | 看 Runtime 是否能感知自身队列之外的硬件占用,以及执行位置是否随外部负载变化 |
| E2 | Runtime workload:通过 Runtime 自身持续提交更多推理任务 | 高 | 高 | 区分 Runtime 已知的内部任务压力和真实硬件忙碌程度 |
| E3 | Waiting workload:在 Runtime 内形成等待任务,同时尽量保持硬件低负载 | 高 | 低 | 看 Runtime 能否区分“队列很长”和“硬件真的很忙” |
这组实验的核心不是单纯把 CPU 打满,而是把“Runtime 自己知道多少任务”和“硬件实际上有多忙”拆开。后续如果要修改 Scheduler,就可以先判断现有策略到底缺的是队列信息、外部负载信息,还是更细的任务特征信息。
当前 E0 / E1 结果
E0 无外部干扰时,100 次推理的平均延迟约为 52.68 ms,吞吐约为 18.98 inference/s,可以作为当前官方 Runtime 的基准。
E1 中把一个 Runtime 外部的负载进程固定到 CPU8-15,并在 8 个 round 中逐核移动。当前结果里最明显的一点是:外部负载位置变化后,推理侧的活跃核分布和性能会随之变化,并不是始终固定在同一个执行位置。以外部负载位于 CPU8 的一轮为例,平均推理延迟上升到约 107.41 ms,吞吐下降到约 9.31 inference/s;当外部负载移动到其余核后,多数组合又回到约 53 ms、18.6-18.8 inference/s 的范围。
这说明当前官方 Scheduler 至少存在对 Runtime 外部硬件负载产生响应的能力。目前仍不能仅靠黑盒数据确认它内部具体读取的是 CPU utilization、某种 cluster 状态、Runtime 统计信息还是其他指标,因此这里暂时不对实现机制下结论。
这个结果也修正了后续工作的方向:后面没有必要从“Scheduler 完全看不到外部负载”这个假设重新做一套检测机制,而应该进一步确认它现有感知能力的粒度和缺口。下一步更值得测的是:
- 同样的负载率下,计算密集和内存密集任务是否会被 Scheduler 区分;
- 外部负载位于同 cluster 和不同 cluster 时,对推理延迟的影响是否有稳定差异;
- PMU 的 stall、cache / memory 等指标能否比单纯的 busy/idle 更早反映资源竞争;
- 如果现有 Scheduler 只能看到“忙不忙”,是否可以在此基础上增加 workload 类型和干扰强度信息。
目前计算密集 / 内存密集的细分对照还没有完成,因此现阶段只能确认“存在外部负载响应”,还不能说明 Scheduler 已经具备 workload-aware 或 PMU-aware 的调度能力。
K3 PMU 与 Raw Event 整理
为了让后续实验不只依赖 htop 或最终推理时间,本周继续整理 K3 上可以稳定读取的 PMU 事件,并把验证结果写入 K3 RawPerfEvent 映射文档。
当前在 K3 Ubuntu 上已经可以通过 Linux perf 对指定核做周期采样,并用微基准交叉验证部分 raw event。现阶段确认 cpu/event=0x03/、cpu/event=0x04/ 与 stalled-cycles-frontend、stalled-cycles-backend 的统计行为能够对应,后续会继续补 cache、memory 和其他可能与资源竞争有关的事件。
这部分工作的目的不是单独做 PMU benchmark,而是给后续 Scheduler 实验提供统一的数据来源:先用 E0-E3 把调度行为分出来,再观察同一时间窗口内 PMU 是否出现稳定差异,最后再决定哪些事件值得真正进入调度策略。
USB:使用 Svpbmt 修复频繁 DMA 访问结构的一致性问题
上一周 USB 已经完成 DWC3 / Host Controller 相关兼容层接入,但枚举链路仍然会在控制器和 CPU 共享的数据结构上出现问题。本周继续排查后,问题集中到 USB 控制器频繁访问的 DMA ring 和相关结构体。
这类内存和普通的一次性 DMA buffer 不太一样:ring、context 等结构会长期存在,并且 CPU 和设备都会频繁读写。如果完全依赖软件在每次所有权变化时做 cache clean / invalidate,很容易遗漏某个同步点。
本周针对这部分常驻 DMA 结构使用 Svpbmt 设置合适的内存属性,使控制器和 CPU 对 ring / context 的观察保持一致。修复后,之前 USB host 在枚举过程中出现的卡死问题消失,上层 crabusb 可以继续完成设备枚举和后续控制传输流程。
目前 USB 软件栈已经从“控制器能检测设备变化”推进到上层 crabusb 可以实际跑通枚举链路。下一步计划通过 USB 接口控制小车,但这部分本周还没有进行实际尝试。
本周问题与判断
- 官方 Scheduler 并不是完全只看 Runtime 自己的任务队列:E1 的外部负载实验已经能观察到调度行为随外部占用变化。后续重点应从“有没有外部负载感知”转到“感知粒度够不够”。
- 当前实验还不能区分 workload 类型:现阶段 external hog 主要用于制造确定的占用,还没有完成计算密集、内存密集等更细的干扰分类,因此不能直接判断现有 Scheduler 是否已经考虑 cache / memory contention。
- PMU 可以作为下一阶段的补充信号,但需要继续校准:目前已经建立基本的
perf采样和 raw event 映射,后续需要先确认事件稳定性、采样窗口和 multiplexing 影响,再考虑放进调度决策。 - USB 的 DMA 内存不能全部按同一种方式处理:一次性流式 buffer 可以继续使用显式 cache 同步,但 controller ring、context 等高频共享结构更适合通过 Svpbmt 明确内存属性。两类 DMA 场景需要分开处理。
后续工作
- 在 E0-E3 框架上继续增加计算密集、内存密集 workload,验证现有 Scheduler 是否只能感知 busy/idle,还是能够识别更细的资源竞争。
- 继续完善 K3 PMU 事件表,重点寻找 cache miss、memory stall、pipeline stall 等对异构调度有实际价值的指标,并测量采样开销和稳定性。
- 根据实验结果重新确定 Runtime Scheduler 的修改位置,优先补现有策略缺失的信息,而不是重复实现已经存在的外部负载检测。
- 在 USB 枚举链路已经跑通的基础上继续验证实际设备传输,并尝试通过 USB 接口驱动小车。