当前位置:首页>Linux>最低 FPS 从 4 飙到 29!Linux 7.3 一个调度补丁,让老电脑游戏性能翻倍

最低 FPS 从 4 飙到 29!Linux 7.3 一个调度补丁,让老电脑游戏性能翻倍

  • 2026-11-02 22:20:42
最低 FPS 从 4 飙到 29!Linux 7.3 一个调度补丁,让老电脑游戏性能翻倍

一位 Intel 内核工程师的一次「手术刀式」改进,让 2011 年的 Sandy Bridge 焕发第二春


一、一个让人揪心的数字:FPS 4

一台 i7-2600K(2011 年发布),配一张 RX 580,跑个游戏——后台挂着浏览器和更新程序。

然后帧率监控告诉你:最低 FPS 4。

不是显卡不够用,不是 CPU 太老。是你的操作系统内核调度器,在 cgroup 层级里迷路了。

这个场景太熟悉了。Steam Deck、老笔记本、客厅 HTPC——任何跑 Linux 的旧硬件,在后台有负载时都会遭遇这种「帧率断崖」。而 Peter Zijlstra 给出的答案,名字就很形象:Flatten The Pick——把选任务的路,压平。


二、EEVDF 很好,但 cgroup 是个坑

2.1 EEVDF 干了件漂亮事

Linux 6.6 合入的 EEVDF(Earliest Eligible Virtual Deadline First)调度器,取代了沿用近二十年的 CFS。它的核心思想优雅而简洁:

每个任务有一个虚拟截止时间,调度器每次都选「最紧急」的那个。

公平性更好,延迟更可控。但有一个问题 EEVDF 没解决——当任务被装进 cgroup 这个盒子的时候。

2.2 cgroup 层级:一个隐形的迷宫

现代 Linux 用 cgroup 管理 CPU 资源分配。你可以把任务分组,给不同组分配不同的 CPU 权重:

root(权重 1024) ├── 游戏组(权重 1024) │    ├── game.exe │    └── steam.exe ├── 浏览器组(权重 512) │    └── chrome └── 后台组(权重 256)      └── updated

看起来很合理。但问题是:调度器怎么从这棵树里选下一个任务?

在 flatten 之前,EEVDF 是这样 pick 的:

  1. 从根 cgroup 开始,计算所有子节点的 eligibility
  2. 选中最「紧急」的子节点(可能是一个中间 cgroup,而不是实际任务)
  3. 进入这个子节点,递归重复步骤 1-2
  4. 直到选到一个实际任务

每经过一层中间节点,都要做一次完整的 enqueue/dequeue 操作。

这就带来了两个问题:

  • 延迟不可控
    :层级越深,pick 路径越长,延迟抖动越大
  • 开销随机放大
    :后台有任务争抢时,调度器在层级间来回奔波,开销叠加

游戏场景最受伤的原因在于:帧渲染对调度延迟极度敏感。一次 100ms+ 的调度抖动,就是一次掉帧。


三、Flatten The Pick:把路铺平

3.1 一句话概括

保留 cgroup 层级来算权重,但让 EEVDF 选任务时走平路。

换言之:cgroup 的层级树继续用于 weight/shares 的财务记账,但调度选择(pick)不再沿着这棵树走,而是在一个平坦的单层 runqueue 上直接挑选。

3.2 数学原理

Peter Zijlstra 在 cover letter 里给出了详细的推导。每个任务在 EEVDF 中的 eligibility 由以下因素决定:

V_i(t) = 虚拟运行时间deadline_i = V_i(t) + (lag / weight_i)

在层级模型中,任务的权重需要乘上所有祖先 cgroup 的权重比例,得到有效权重(F_g^d 项)。原来的做法是在 pick 时动态计算这个值——这就要求遍历层级。

Flatten 的洞察是:权重可以在 enqueue/dequeue 时预先折算好,pick 时直接用。这样 EEVDF 的 pick 操作从递归遍历变成 O(1) 的直接选择,数学上的公平性等价性保持不变。

3.3 架构变化

方面
改之前
改之后
pick 路径
递归遍历 cgroup 树
单层 runqueue 直接选
cgroup 层级职责
记账 + 调度选择
仅负责权重计算
中间节点
是调度候选
被 bypass
pick 复杂度
O(树深度)
O(任务数)
延迟抖动来源
中间节点入队/出队
已消除

3.4 新增的 cgroup_mode

为了让平坦 runqueue 工作得更顺滑,patch 引入了一个调试接口:

/sys/kernel/debug/sched/cgroup_mode
五种模式
含义
concur
(🏆 新默认)
使用任务组内活跃任务数计算权重,避免过小的 F_g 值
tasks
简单任务计数模式
max
权重上限模式
up
优先级提升模式
switch
模式切换机制

Peter 的 commit message 写得很坦诚:

“改变默认值肯定会有问题……但新架构下旧的权重计算方式会放大不公平性。既然可配置,就改默认值,希望更多人受益。”


四、数据:从 4 到 29

测试平台:Intel Core i7-2600K + AMD Radeon RX 580(Lutris/Proton)

帧率

指标
改之前
改之后
改善
最低 FPS4.029.0+625% 🔥
平均 FPS
47.5
59.2
+25%

帧时间(越低越好)

指标
改之前
改之后
改善
平均帧时间
34.0 ms
17.0 ms
减半
最大帧时间121.2 ms30.0 ms-75% 🔥

关键解读:

  • 最低 FPS 4→29
    :意味着「卡成幻灯片」的场景变成了「不富裕但流畅」。这是体感改善最大的部分。
  • 最大帧时间 121ms→30ms
    :这个指标直接对应 micro-stutter(微卡顿)。121ms 意味着每几秒就有一帧卡住超过 1/8 秒——人眼完全能感知到。降到 30ms 后,这种卡顿基本消失。

Peter 选 i7-2600K 做测试是有意为之——这是 2011 年的 CPU,正是「potato hardware」的典型代表。如果这个改进在它上面有效,那任何现代 CPU 只会更好。


五、交叉映射:这不是第一次「压平」

Linux 内核历史上,类似的「压平」改进并不少见:

领域
改进
类似思路
调度器
Flatten The Pick
把 cgroup 层级从 pick 路径中剥离
内存管理
Maple Tree(v6.1)
替代红黑树管理 VMA,减少层级遍历
文件系统
io_uring
绕过 VFS 层,直接操作 block layer
网络
XDP
在网卡驱动层处理包,绕过网络协议栈

它们的共同模式是:当一个层级结构从「管理工具」变成了「性能瓶颈」,就把它从热路径(hot path)中剥离出去。

Flatten The Pick 的优雅之处在于它没有推翻 cgroup——cgroup 的权重计算仍然保留层级。它只是把「选任务」这件事从层级中解耦出来。这种最小侵入式优化,是内核 hacking 中非常难得的好品味。


六、谁受益?

  • 🎮 游戏玩家
    :最低帧率大幅提升,Proton/Lutris 场景尤其明显
  • 📦 容器/虚拟化
    :cgroup 层级越深,收益越大。K8s 环境下多级 cgroup 的调度延迟显著降低
  • 🏢 多租户服务器
    :cgroup 隔离环境下的调度行为更可预测
  • ⏱️ 低延迟/实时场景
    :消除了中间实体入队/出队的抖动源

换言之,所有跑 Linux 7.3+ 的设备都会受益,只是游戏场景最容易被人感知到。


七、时间线与总结

版本
时间
状态
v1 RFC
2026-03
8 patches,首次提出 flatten 思路
v2
2026-05
修复 hackbench 回归
v32026-067 patches,合入 tip/sched/core
Linux 7.32026-08(目标)合入主线

Flatten The Pick 是一次精准的手术式改进。不长篇大论,不推倒重来,不引入新框架。它只改了一件事:让 EEVDF 选任务的时候,不再绕路。

有时候,最好的性能优化不是加更多东西,而是把路铺平。


参考来源:

  • Phoronix: Linux 7.3 Expected To “Flatten The Pick”
  • Phoronix: “Flatten The Pick” Linux Patches Progress
  • LWN: sched: Flatten the pick (RFC)
  • Peter Zijlstra v3 patch series on LKML
  • v3 patch 7/7: sched/eevdf: Move to a single runqueue

最新文章

随机文章