第 4 章 JudgeDuck-OS 作为 runtime
重审 JudgeDuck-OS 的契机,不是“顺手改了点内核”,而是被真实的端到端开销逼着去重新定义它的职责。
4.1 最初的抽象边界:为什么不是常驻服务
一个更早的边界需要先说清:为什么最初没有直接把 duck 侧做成“常驻服务”,而是继续复用 JudgeDuck-OS 原有的“一次评测一个 ELF”抽象。
原因并不复杂,而是当时很务实的工程判断。
如果把 duck 侧做成 userspace 常驻程序,就需要给 userspace 打开网络接口,或者重新发明一套 syscall / IO 机制;如果做成 kernel 内常驻程序,实现路径也许更短,但程序一旦写错,更容易把整台机器直接打崩。相比之下,JudgeDuck-OS 原本那套“给一个 ELF,跑完就退出”的模型,虽然 launch 成本高,却有一个当时非常重要的优点:它已经是个被长期使用过的沙箱,程序在里面挂掉,不会顺手把整台鸭子搞坏。
所以早期的选择不是“没想到 persistent”,而是先复用一个更稳、更容易调试的执行抽象。后面系统确实会继续演化出 persistent judge,把 launch 成本往下压;但那已经属于第 8 章里 fp9 扩成完整远端路径之后的事情了。
4.2 触发点:算力已经够了,开销却还在
这件事发生在 2025 年 8 月 31 日。
此前,duck-llm 已经完成了 Qwen3 dense 和 MoE 的初步接入,也做了 fp8 dequantization 支持。duck 侧的单层 compute 已经压到了 2.x ms 量级——这个数字本身是合理的,意味着权重 GEMV 的计算逻辑在鸭子上已经跑通了。
但端到端测量时,整条链路的延迟却仍在 12 ms 左右。其中 JudgeDuck-OS 一侧就能吃掉约 11.5 ms。
单层算一次只要 2 ms,但把这次算完到下一步能开始,却要等 12 ms。中间那将近 10 ms 去哪了?
这是整个 JudgeDuck-OS 重审工作的出发点。在这之前,JudgeDuck-OS 的定位是“在线评测系统”——给定一个 ELF,运行,计时,返回结果。它被设计成适合跑完就退出、下次再启动一个新实例的单次评测模式。现在需要的,是另一件事:把它当成一个可以被高频反复召唤的远端 kernel launcher。
这两件事对延迟的要求完全不同。
4.3 第一波:五处可见的固定成本
2025 年 8 月 31 日,JudgeDuck-OS 仓库在一天之内连续落了五个提交,每个提交都对应一处具体可见的开销。
Enable AVX(bbf244f)
首先做的是让 N100 的 AVX 指令集真正可用。JudgeDuck-OS 原来的初始化路径没有打开 AVX 扩展状态(XCR0),这意味着即使程序里写了 AVX 指令,也会以异常或慢路径方式执行。打开 AVX 是后续所有 SIMD 优化的前提。
Fast ELF loading(6f249af)
这个提交解决了 load elf 5ms 的问题。
原来的 ELF::load() 路径在装载每个新 ELF 时,会对整段物理内存范围做一次页表标志位刷新(Memory::set_page_flags_kernel),无论这次 ELF 和上次有多少重叠。改动的核心思路是:只处理“上次装载范围”和“这次装载范围”之间的差量,并在 set_page_flags_*() 里加上 start >= end 的 fast path。
效果直接:load 时间从约 5 ms 压到了可忽略量级。
Load IB by memory-map(7f2d1eb)
这个提交解决了 memcpy/IB 3ms 的问题。
原来的 input buffer(IB)传输路径,不管大小都走 memcpy——judge 每次启动时,host 把输入数据复制进 duck 的 IB 区域。对于 MoE forward,要下发多个 expert 的权重,IB 会很大,3 ms 的复制开销直接叠在了每次 forward 的关键路径上。
改动的核心是:当 IB_ptr 与 IB_size 满足页对齐时,不再分配/复制 IB,而是直接按页映射(mmap 语义)。judge 结束后显式 cleanup_mappings(),防止这层 mmap 残留影响下一次运行。
这一步把“input buffer 传输”从热路径里真正摘掉了,而不只是压缩了它。
Skip wbinvd(a3ea37c)
一个 wbinvd 指令大约需要 0.4 ms——这并不是一个可以忽略的数字,当 MoE forward 目标是 1~2 ms 时尤其如此。
wbinvd(Write Back and Invalidate Data Cache)是 x86 的特权指令,执行时会把整个 CPU 的 L1/L2/L3 cache 刷回内存并失效。原来的 JudgeDuck-OS 在 syscall return 路径(trap_entry.S)上留有这条指令。
改动是直接把 syscall return 路上的 wbinvd 注释掉。对于 remote kernel 执行场景,每次 forward 结束时不需要强制冲刷整个 cache——这是评测场景留下的老习惯,在 LLM 推理场景里是纯粹的浪费。
Update scheduler config(44c8c7e)
原来的 idle 策略是:idle 1 ms 之后就 sleep 1 ms。
在高频 forward 场景下,这意味着 duck 可能在两次 forward 之间进入短暂的睡眠,然后被 host 的下一次请求唤醒——这个唤醒延迟是不可预测的,而且在 forward 间隔很短时可能让 duck 反复经历“sleep → wake”的开销。
改动是把 idle 超时从 1 ms 改成 10 ms,也就是 duck 要在没有任何事情做足 10 ms 才会进入短睡眠。对于高频推理场景,这意味着 duck 在两次 forward 之间通常会停留在 idle polling 状态,而不是误入 sleep。
4.4 一周后:按真实 workload 重排 buffer 配置
2025 年 9 月 7 日,9f9177e Update buffer/cache config。
这个提交把 BUFFER_CACHE_SIZES 扩展到了更多更大的候选项,从原来的 4 GiB 上限一路补到 32 GiB,同时把保留给程序执行的 run_program_size 预算从 3072 MiB 改到 512 MiB。
这说明 2025-08-31 那天的重审并没有在“把最显眼的几个 ms 干掉”之后就停止,而是继续往“让 JudgeDuck-OS 的 buffer 分配策略适配真实的 duck forward workload”方向推进。
4.5 第一阶段的结果
到 2025-09-07,这一轮第一阶段 JudgeDuck-OS 重审已经形成一个很清楚的提交簇:
| 提交 hash | 日期 | 说明 |
|---|---|---|
bbf244f | 2025-08-31 | Enable AVX |
6f249af | 2025-08-31 | Fast ELF loading |
7f2d1eb | 2025-08-31 | Load IB by memory-map |
a3ea37c | 2025-08-31 | Skip wbinvd |
44c8c7e | 2025-08-31 | Update scheduler config |
9f9177e | 2025-09-07 | Update buffer/cache config |
这 6 个提交已经足够说明,JudgeDuck-OS 在这一阶段经历的不是零散维护,而是一次职责上的变化:它开始从“单次评测 OS”转向“低延迟远端 runtime”。
到这个时间点,多核执行能力还没有真正做出来,常驻会话也还没有出现。系统首先完成的,是把单次启动路径里最显眼、最浪费时间的固定成本打掉。
项目声明 / Project Disclaimer
本项目为作者以个人身份、利用业余时间推进的个人娱乐项目;除非另有明确说明,它与作者的任何雇主、客户、学校、单位或其他组织均无合作、雇佣、委托、赞助或背书关系,也不代表任何该等主体的立场。除普通个人捐赠外,本项目未获得任何资金支持。
This project is a personal hobby project developed by the author in a personal capacity and in personal time. Unless explicitly stated otherwise, it has no collaboration, employment, commission, sponsorship, endorsement, or institutional affiliation with any employer, client, school, partner organization, or other entity, and it does not represent any such party's views. No funding was received for this project except ordinary personal donations.
许可 / License
除非另有说明,本页原创文字、本站原创图片与本站原创图表采用 CC BY-NC-ND 4.0 发布。
转载时请保留原文标题、署名“JudgeDuck AI”、发布日期与原始链接;禁止商业转载、改写、摘编、翻译或基于原文创作演绎作品。
第三方商标、外部链接内容,以及文中另有标注的材料,不在上述许可范围内。
Unless otherwise noted, the original text, original images, and original figures on this page are licensed under the Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.