Cache Aware Scheduling(CAS,缓存感知调度):它解决什么硬件问题、老调度器为什么瞎、7.2 里到底改了哪几处、收益边界在哪、以及怎么开。
一、先说硬件背景:现代 CPU 不是"一整块 L3"
以前低端多核时代,一个 socket 内所有核共享同一片 L3,调度器把任务扔到哪个核差别不大。
但现在服务器端和高端桌面是这样:
- AMD EPYC / Ryzen(Zen 2+):多 CCD(Core Complex Die),每个 CCD 自带独立 L3,CCD 之间通过 Infinity Fabric 互联。
- Intel Xeon 6(Granite Rapids / Clearwater Forest):多 tile 设计,每个 tile 有独立 LLC 区域;加上 P/E 混合核,拓扑更复杂。
- ARM 多集群服务器:不同 cluster 后挂的 LLC/DSU 也不一定统一。
于是"末级缓存域(LLC domain)"成了一个比 NUMA 节点更细、比核心更粗的关键边界:
- 同 LLC 域内共享数据 → 命中 L3,几十 cycle
- 跨 LLC 域共享数据 → 要走片上互联 + 缓存一致性协议(MOESI 之类),可能 40--100 cycle 级别惩罚,还占带宽、引发 cache bouncing(同一缓存行在多域间反复失效)
老 CFS/EEVDF 负载均衡只认"这个核闲不闲、NUMA 归谁、SMT 兄弟是谁",不认 LLC 边界,所以同进程的多线程可能被甩到两个 CCD 上,互相踩热数据。
二、CAS 在 7.2 里具体干了啥
合入路径:Intel 工程师主导,Peter Zijlstra 走 sched/cache 分支合入 7.2 合并窗口,Kconfig 开关是 CONFIG_SCHED_CACHE (注意:默认关闭,需要发行版或你自己编译开启)。
核心机制分四步:
- 启动期建拓扑图
通过 CPUID /x86_cache_topology把每个 CPU 归属哪个 LLC domain 编号算出来,挂进调度域层次结构。 - 任务打标签
跟踪任务最近在哪段 LLC 上跑、缺页时页面来自哪个 domain,在task_struct层面记录倾向(同进程线程自然共享倾向)。 - 选核与迁移时加权
- 空闲核选择:优先选"和任务 cache_domain 标签一致"的核
- 负载均衡:跨 LLC 迁移被赋予更高代价权重,不是绝对禁止,但比跨 NUMA 内同 LLC 的迁移更保守
- 同进程线程唤醒(wakeup)时,倾向落到同一 LLC 的兄弟核
- 防热点兜底(很重要)
纯"黏缓存"会把一个 CCD 塞爆,所以加了护栏:- 某进程已占该域 CPU 时间 >25%,或
- 该域总负载被它吃掉 >1/3
→ 调度器放弃共置,退回普通均衡扩散。
另外顺手改了些调度器自身热路径的 cfs_rq / sched_entity 布局,让"感知缓存的调度器"自己别引入额外 cache miss。
运行时若内核开了 debugfs,可做 A/B:
cat /sys/kernel/debug/sched/llc_balancing/enabled
echo 0/1 > /sys/kernel/debug/sched/llc_balancing/enabled
三、为什么对 Intel / AMD 多核"显著"提升
受益前提是**"多线程 + 真共享内存 + 工作集能塞进单 LLC"**:
- 数据库(MySQL/PG/Valkey/Mongo):连接线程、worker 共享 buffer pool / 锁结构
- DPDK / 网络后端:流水线线程传 mbuf
- AI 推理后端:batch 内线程共享权重张量缓存
- 并行编译(make -j / ninja):共享头文件与中间对象
早期基准(Phoronix 及后续扩展补丁,最佳情形):
- AMD EPYC Turin:MySQL OLTP 吞吐最高 +360% (极端共置友好负载),常规 PG/Valkey 约 15--44%
- Intel Xeon 6:Web 服务延迟约 −17% 、RPS +12% ;DB 事务延迟 −15% 、吞吐 +17%
- 视频编码类吃 LLC 吞吐的:挂钟时间 −16%
- 单线程、或工作集远大于 L3(纯内存带宽瓶颈)、或已用
taskset/cpuset钉死的任务 → 基本零收益
嵌入式侧要注意:很多 ARM SoC 全簇共用一个 DSU+L3,即"只有一个 LLC domain",CAS 对它完全无效,别盲目期待。
- "7.2 引入 CAS"------准确说是 7.2 合并窗口合入主线 ,但是 opt-in 特性 ,Ubuntu 26.10 / Fedora 等装不装、开不开
CONFIG_SCHED_CACHE是发行版决策,不是升级内核自动生效。 - 把 CAS 和"GPU DRM 调度改公平策略"并列,但 7.2 稳定版里 DRM 调度因 AMD 回归又 revert 回 FIFO 了,CAS 才是真正落住的核心调度改动。
- CAS 目前是"同进程/同组任务共置"的第一层;后续 Hygon 等还在做层次化拓扑感知聚合(跨域动态扩缩),7.2 只是地基。
五、一句话定性
CAS 不是魔法,而是把"现代 CPU 多 LLC 分片 "这件硬件事实,第一次正经写进 CFS/EEVDF 的迁移代价函数里:能共置就共置,共置会过热就撤,不改应用代码、不碰 NUMA 策略,在多 CCD EPYC / 多 tile Xeon 上给多线程服务端负载换一份"免费"的延迟和吞吐红利------前提是你用的内核真把它编进去了。