第45期 | 进一趟内核,要交多少过路费
一、先把自己敲晕,再叫醒
1991 年的 Linux 0.01,应用程序进内核只有一条路:int 0x80¹。这是一条"自己打自己"的指令——CPU 收到它,立刻停下手头的事,把 eflags、cs、eip 自动压栈,特权级从用户态的 3 级切到内核态的 0 级,跳进 system_call。还没完:内核入口第一件事,是把剩下的寄存器一个个亲手压栈保存,干完活再原样弹回来²。光这套"敲晕—保存—恢复"的仪式,就是一笔跟活儿大小无关的固定开销——真正的活儿(比如读几个字节)常常只占零头,过路费比货值贵。
门的设计从第一天就是这样:UNIX 1974 年的论文里,"陷阱与信号"是正经的一节³——硬件故障、interrupt、quit,都走同一套"被打断—保存现场—处理—恢复"的路。五十年,形状没变,变的只有快慢:后来 CPU 厂商专门造了 sysenter 这类快进快出的指令⁴,就是为了把这套仪式走得更快。注意,这全是发展性研究:没发明新原理,就是把"进出门"这个动作磨到极致——先实际后原理,磨的是同一条路。
二、没有门,意图一次交待完
如果 AI 的操作系统先出现,门可能根本不会长成"一次敲一下"的样子。一个 agent 的意图,常常对应几十次系统调用:读文件、建连接、开进程。贵的不再是干活,是开门。AI OS 会把"交待"批量化:像 io_uring 那样,一次把一整批请求摆进环形队列,内核异步干完再统一收结果——门从"转门"变成"传送带"。
而 vDSO 已经把终局剧透了:门最好的优化,是"不用进门"。问时间、问 CPU 号这种调用,答案对所有进程都一样,也不涉密,内核干脆把答案抄在一页用户态可读的内存里(vDSO),调用退化成普通函数调用加几次内存访问⁵⁶。AI-native OS 里,agent 的世界模型就住在内存里,查状态根本不用敲门——门会越来越少,共享的"纸条"越来越多。范式之眼在这里最锋利:门是为顺序指令流设计的,一次陷阱服务一条指令流;可今天的算力主体是向量阵列,它的活儿从来都是批量提交的。io_uring 的提交队列,就是新范式给旧门画的第一张草图。
三、找出那个偷偷不进门的:三件事,今晚就能亲手验。
第一,看那页"纸条":`cat /proc/self/maps | grep vdso`,再 `ldd /bin/ls | grep vdso`——每个进程出生时,内核都往它的地址空间里塞了一段"不存在的共享库" linux-vdso.so.1。
第二,看一场"隐身":`strace -e trace=gettimeofday,getpid date`。你会看见 getpid 被 strace 拦下来(真进门了),而 gettimeofday 一次都不出现——它走 vDSO,根本没敲门。strace 是门上的摄像头,vDSO 走的是侧门。
第三,亲手量一量过路费:写个十行的小程序(C 或 Python 的 timeit 都行),getpid 跑一百万次计时,clock_gettime 跑一百万次计时。前者每次都交过路费,后者基本白嫖——数量级的差距,亲手数一遍就信了。
落到日常工程里:边缘设备上做高频定时采样,直接调 clock_gettime(glibc 默认已经走 vDSO),别自己造轮子每次进内核取时间;做 agent 编排时,把"一个意图→几十次调用"合并成批量提交(io_uring 的思路),别让智能体像讨饭一样一次敲一次门。门越少,智能体越快。
觉 然 小 注
最好的门,是让人忘了门存在的那扇。vDSO 干的,就是这件事。
引 用 与 出 处
- [1] linux-0.01 源码结构解析. DeepWiki. https://deepwiki.com/liudonghua123/linux-0.01
- [2] syp2023. 理解 Linux 内核第 10 章系统调用学习笔记. 博客园, 2023. https://www.cnblogs.com/syp2023/p/18223897
- [3] Ritchie, D. M. & Thompson, K. The UNIX Time-Sharing System. Communications of the ACM, 1974. https://doi.org/10.1145/361011.361061
- [4] SYSENTER/SYSEXIT vs INT 0x80. exchangetuts.com. https://exchangetuts.com/sysentersysexit-vs-int-0x80-1641007203984029
- [5] Anvin, H. P. Document the vDSO and add a reference parser. Linux 内核提交 98eedc3a, 2011. https://gitlab.utc.fr/mi11/linux/linux-raspberrypi/-/commit/98eedc3a9dbf90cecb91093d2a7fa083942b7d13
- [6] Linux man-pages 项目. vdso(7). https://manpages.ubuntu.com/manpages/focal/en/man7/vdso.7.html
· · ·