我在 macOS 上跑 300GB 模型却没用 O_DIRECT:为什么绕过 Page Cache 反而慢 2 倍
你打算把一个装不进内存的模型放到 SSD 上流式跑,第一反应大概是去翻O_DIRECT的用法,接着翻io_uring,结果在 macOS 上发现前者根本不存在、后者更没有。于是你转去查fcntl(fd, F_NOCACHE, 1),查到一半会看到 Apple 开发者论坛上一句让人心凉的话:它是个 hint,不保证生效,而且不会清掉已经缓存的页。DwarfStar 的 ds4 引擎能在一台 128 GiB 的 Mac 上把一个三百多 GiB 的 MoE 模型跑起来。我把整棵源码树 grep 了一遍,O_DIRECT零次,F_NOCACHE零次,io_uring零次。它用的是最朴素的 bufferedpread。这件事第一眼看上去像是“没做优化”,实际上恰恰相反。真正决定这台机器是能出 token 还是四十分钟后开始重度换页的,从来不是你有没有绕过 page cache,而是这几十 GiB 内存的所有权最终记在谁头上——记在内核的 page cache 上,它随时可以在你最需要的时候把它回收掉;记在你自己 mlock 住的 slab 上,它就是你的。这套实现干的全部事情,就是把所有权从前者一寸一寸挪到后者,同时在驱逐的时候主动把前者按回去。下面我会带你把这条链路从最外层的一行命令拆到最里层的pread落点:先用一个专门用来“制造内存不足”的工具把“模型必须装进 RAM”这个前提实测崩掉;再算清楚 MoE 到底给了我们什么样的结构性机会;然后逐行读d