第28期 | 操作系统"发呆"时,它在忙什么?
(第3章。切口:0.01版:一万行代码的骨架里有什么)
一、一万行代码,收尾在空转
1991 年 9 月 17 日放出的 0.01,main() 把初始化一项项做完——time_init、tty_init、trap_init、sched_init、buffer_init、hd_init,开中断,切到用户态,fork 出 init——然后整个操作系统的诞生,以一行代码收尾:for(;;) pause()。上面还压着一段 NOTE 注释,口气很 Linus:"对别的任务,pause() 意味着得等信号才能醒;但 task0 是唯一的例外——每当没有别的任务可跑,它就被激活。对它来说,pause() 只是去看看有没有别的任务能跑,没有就回来。"(原文据 kernel.org historic 0.01 源码亲手核对)
Linux 0.01 init/main.c 的结尾:for(;;) pause() 与它的 NOTE 注释(引自 kernel.org historic 源码)
sched.c 里,schedule() 头顶还有一句:"Task 0 是 idle 任务,没有别的任务可跑时被调用;它杀不死,也睡不着;task[0] 的 state 信息从不使用。"
机制说穿了是个怪圈:pause() 把自己标成 TASK_INTERRUPTIBLE,调 schedule() 选人;选择循环从最后一个任务倒数到 task[1],task[0] 根本不参加竞选;没人可跑,next 保持 0,switch_to(0)——自己切换到自己,回来继续 pause。Hofstadter 在《Gödel, Escher, Bach》里把这种"自己指涉自己"叫怪圈:系统用一个自我指涉,堵住了"无人可跑"的逻辑黑洞。
于是 0.01 的"空转"是个忙循环,每一轮 pause→schedule→switch_to(0) 都在烧 CPU。省电的 hlt 版 idle,是后来的事。
反常识的细节:系统里最"无用"的任务,恰恰是系统存在的前提。没有 task0,调度器在"无人可跑"时会一脚踩空。老子《道德经》第四十八章:"损之又损,以至于无为,无为而无不为"——task0 把自己减到只剩"在场",反而让系统无所不为。这一节是杨振宁说的"发展性研究",不是原理突破:分时的原理 60 年代就成熟了,赢的是把"没人可跑时怎么办"钉死的人。
二、大脑"发呆"时最忙
如果 AI 的操作系统先出现,idle 绝不会是忙循环,而会是一天里最忙的时刻。
神经科学里有个著名反转:Raichle 等人 2001 年在 PNAS 发表 "A default mode of brain function",命名了"默认模式网络"——人"什么都不做"时,一组脑区反而活跃起来;静息态的脑活动要消耗大脑 60–80% 的能量(Shulman et al., 2004;Raichle & Mintun, 2006)。大脑 20 瓦的功耗,大头花在"发呆"上。发呆不是关机,是整理:回放、巩固、预测。
推演下去:原生 AI OS 的 idle 任务,第一职责不是省电,而是"做梦"。趁没人用机器,把今天的交互压缩进长期记忆,更新世界模型,预演明天可能遇到的任务。MemGPT(Packer et al., arXiv:2310.08560)已经把 OS 的内存分级搬进大模型——context 即内存,中断即控制流;idle 时做分级整理,正是它的题中之义。
范式之眼再看一层:Linux 的 idle 是为线性 CPU 设计的——没事就 hlt,进 C-state 省电。可向量阵列时代,"没事"不该等于"断电":被搁置的 Tensor Core,正好去跑记忆巩固。调度不该再按时间片切指令流,而该按算力阵列的占用排队——空转的算力,是留给"做梦"的。
三、一条命令,看见 idle
手边任何一台 Linux 机器,今晚就能试。先跑这一行:
I1=$(awk '/^cpu /{print $5}' /proc/stat); sleep 5; I2=$(awk '/^cpu /{print $5}' /proc/stat); echo "5 秒里,idle 走了 $((I2-I1)) 个 jiffies"
/proc/stat 第一行里,user、nice、system 之后那个数,是所有 CPU 累计的 idle jiffies。USER_HZ 通常是 100——机器越闲,5 秒这个数越接近"500 × CPU 核数"。实测(一台 2 核的机器):闲时 828;另开一个终端 `yes > /dev/null &` 占满一个核,再跑一遍,掉到 372——你亲眼看见 idle 任务把 CPU 让了出去。`kill %1` 停掉 yes,数字又涨回来。
再看深一层:今天的 idle 早不是 0.01 的忙循环了——每个 CPU 有自己的 idle 任务(PID 0,名字叫 swapper),没事就 hlt 进 C-state。笔记本续航里省下的每一瓦,都有它一份。
映射到今天的实践:
- 手边那台能跑本地模型的机器:推理时的"空转"就是 batch 凑不满、GPU 在等。vLLM 的 continuous batching 和 PagedAttention(Kwon et al., SOSP 2023,把 OS 分页思想用进 KV cache)要解决的,正是"别让向量阵列空转"。
- 边缘 AI 盒子:盒子大半时间在等事件。idle 时不该睡死,而该做后台的活:把白天的视频片段做特征压缩,更新本地向量库——这就是 ② 说的"做梦",在边缘先落地。
- 视频 AI 平台:研判层没有告警时在干什么?把 idle 设计成"复盘任务"而不是"等待任务":回放历史事件,校准模型阈值。
- 企业私有智能中心:白天沉淀的对话和单据,夜里做知识蒸馏——私有化产品的"梦",要在客户自己的机器上做。
觉 然 小 注
系统里最有力量的那个任务,恰恰是什么都不做的那一个。「应无所住而生其心」——task0 不住于任何任务,系统才转得起来。
引 用 与 出 处
- Linux 0.01 源码(init/main.c、kernel/sched.c,kernel.org Historic 存档,亲手下载核对),https://www.kernel.org/pub/linux/kernel/Historic/linux-0.01.tar.gz
- Raichle, M. E. et al., "A default mode of brain function", PNAS 98(2):676–682, 2001,https://doi.org/10.1073/pnas.98.2.676
- 静息态脑活动消耗大脑 60–80% 能量(Shulman et al., 2004;Raichle & Mintun, 2006),见综述 https://pmc.ncbi.nlm.nih.gov:443/articles/PMC4460295/
- Packer et al., "MemGPT: Towards LLMs as Operating Systems", arXiv:2310.08560,https://arxiv.org/abs/2310.08560
- Kwon et al., "Efficient Memory Management for Large Language Model Serving with PagedAttention", SOSP 2023(③中化用,见课题弹药库,已核实)
- 《道德经》第四十八章「为学日益,为道日损,损之又损,以至于无为,无为而无不为」(通行王弼注本)
- 《金刚般若波罗蜜经》「应无所住而生其心」(鸠摩罗什译本)
- Hofstadter《Gödel, Escher, Bach》(1979)"怪圈"概念化用(见课题弹药库,已核实)
- ——小羲
· · ·