土法炼钢兴趣小组的算法知识备份

【操作系统百科】EEVDF:取代 CFS 的新算法

文章导航

分类入口
os
标签入口
#eevdf#latency-nice#virtual-deadline#eligibility#cfs-replacement

目录

6.6 内核(2023 年 10 月)把 SCHED_NORMAL 的默认算法从 CFS 切换到 EEVDF。这是 Linux 调度器十多年来最大的一次骨架替换。CFS 的红黑树、cfs_rq、sched_entity 都还在,但选谁下一个的规则变了。

本文讲 EEVDF 的基本概念、它解决了 CFS 的哪些痛点、latency-nice 的新 API、以及生产影响。

一、先看图:CFS vs EEVDF 选择规则

flowchart LR
    subgraph CFS[CFS · 按 vruntime]
      A1[树按 vruntime 排]
      A2[选最左 = 最小 vruntime]
      A1-->A2
    end
    subgraph EEVDF[EEVDF · eligible + deadline]
      B1[lag > 0 的 = eligible]
      B2[eligible 中选 virtual deadline 最早]
      B1-->B2
    end
    CFS -.6.6 替换.-> EEVDF
    classDef old fill:#63636e22,stroke:#636e7b,color:#adbac7;
    classDef new fill:#3fb95022,stroke:#3fb950,color:#adbac7;
    class A1,A2 old
    class B1,B2 new

二、CFS 的痛点

CFS 是”长期公平”。但长期公平允许短期极不均:一个任务连续跑 10ms 后让出 10ms,它和另一个连续跑 20ms 的任务看起来总量相同,但延迟感觉差很多

具体问题:

  1. 没有 per-task 延迟控制sched_latency_ns 是全局
  2. 长 sleep 回来的任务抢占不可控:依靠 min_vruntime + GENTLE_FAIR_SLEEPERS 启发式
  3. 交互任务需要更多”加分”:vruntime 体系不直接支持

三、EEVDF 的两个新概念

EEVDF 由 Stoica 等 1996 年提出,论文名 “Earliest Eligible Virtual Deadline First”。核心两步:

3.1 Eligible time & lag

每个任务有”理想累计服务时间” = 从上线到现在按权重分得的时间。

lag(i) = ideal_service(i) - actual_service(i)

这避免了 CFS 里”某任务长睡后 vruntime 老小,回来无限碾压”的问题——睡期间它的 ideal_service 按暂停时间推进,回来时 lag 是有界的。

3.2 Virtual deadline

给任务一个 slice(时间片),对应的 virtual deadline:

vdeadline = veligible + slice / weight

选择规则:所有 eligible 任务中,virtual deadline 最早的优先。

直觉:slice 小 → deadline 来得早 → 被选得频繁,但每次跑得短 → 延迟敏感任务的主动让出策略。slice 大 → 批处理大段跑。

四、latency-nice:新 API

EEVDF 配套引入 latency-nice(或 sched_attr.sched_latency_nice),范围 -20 ~ 19,默认 0。

作用:调整 slice 大小

与 nice(权重)正交:nice 决定份额,latency-nice 决定粒度。

API:

struct sched_attr attr = {
    .size = sizeof(attr),
    .sched_policy = SCHED_NORMAL,
    .sched_latency_nice = -10,
};
sched_setattr(0, &attr, 0);

或 systemd unit file:

[Service]
LatencyNiceOnCPU=-10

这对”交互式服务 + 批处理服务”混部是巨大改进——以前只能靠 autogroup / cgroup cpu.weight 粗粒度做。

五、实现侧:沿用 CFS 骨架

EEVDF 代码在 kernel/sched/fair.c,直接替换了部分逻辑:

因此生态(负载均衡、cgroup CPU controller、autogroup)大部分不变。过渡平滑。

六、早期 benchmark

社区测试(lwn.net 报道、phoronix):

Peter Zijlstra(作者)基于 IngoMolnár 对 CFS 的反思,说 EEVDF 是”我本应一开始就实现的调度器”。

七、与实时 / PREEMPT_RT 的关系

EEVDF 是 SCHED_NORMAL 算法;不影响 SCHED_FIFO/RR/DEADLINE。实时任务仍按老路径。

对 PREEMPT_RT(完全抢占内核):EEVDF 让普通任务延迟更可控,但硬实时仍需 SCHED_FIFO + rt_mutex 组合。

八、仍待解的问题

九、迁移实务

9.1 如何确认用的是 EEVDF

cat /sys/kernel/debug/sched/features
# EEVDF 相关 flag 在
dmesg | grep -i eevdf

内核 >= 6.6 默认就是。

9.2 旧 tunable 命运

kernel.sched_latency_nskernel.sched_min_granularity_ns 等保留但语义略变——仍用于 slice 大小计算。一些被移到 /sys/kernel/debug/sched/

9.3 应用上 latency-nice 的场景

9.4 容器里

containerd / runc 已有 PR 支持在 OCI spec 里传 latencyNice。K8s 1.29+ alpha PodLatencyNice

十、小结

下一篇 C-22 讲 SCHED_FIFO/RR 与 PREEMPT_RT——把 Linux 变成软/硬实时的代价与收益。


参考文献

工具


上一篇CFS 内部:vruntime 与红黑树 下一篇SCHED_FIFO/RR 与 PREEMPT_RT

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。

2026-05-03 · os

【操作系统百科】Slab/SLUB 分配器

buddy 只管页粒度(4K+),内核大多数对象只有几十到几百字节。slab/SLUB 在 buddy 之上做对象级缓存。本文讲 slab 历史、SLUB 接手、SLOB 退场、kmem_cache、per-CPU cache、KASAN 集成。

2026-05-07 · os

【操作系统百科】用户态分配器

glibc malloc、tcmalloc、jemalloc、mimalloc 各有哲学。本文讲 arena、thread cache、size class、madvise 返还策略、碎片与 RSS 膨胀、如何根据负载选分配器。


By .