当前位置: 首页 > news >正文

sched_fair 调度:负载权重、虚拟运行时间与最小虚拟时间

在 Linux 的 CFS(Completely Fair Scheduler,完全公平调度器) 中,负载权重(Load Weight)、虚拟运行时间(vruntime)、最小虚拟时间(min_vruntime) 是三个核心概念,共同决定了任务的调度优先级和 CPU 时间的公平分配。下面详细解析它们的含义、计算方式及相互关系。


1. 负载权重(Load Weight)

(1)作用

  • 决定任务对 CPU 时间的“占有比例”,权重越高,获得的 CPU 时间越多。
  • 由任务的 nice 值映射而来(nice 值越低,权重越高)。

(2)计算方式

  • Linux 使用 sched_prio_to_weight 数组将 nice 值(-20 到 19)映射为权重:
    static const int sched_prio_to_weight[40] = {/* -20 */ 88761, 71755, 56483, ..., 1024, 820, 655, 526, 423, 335, 272
    };
    
    • nice=0 的权重为 1024(基准值)。
    • nice=-20(最高优先级)的权重为 88761,是 nice=086.5 倍
    • nice=19(最低优先级)的权重为 15,仅为 nice=01.5%

(3)对调度的影响

  • 任务运行时间计算
    • 任务实际获得的 CPU 时间 = 调度周期 × (任务权重 / 所有任务权重之和)
    • 例如:若系统有两个任务,权重分别为 1024(nice=0)和 820(nice=1),则 nice=0 的任务获得 1024 / (1024 + 820) ≈ 55.5% 的 CPU 时间。

2. 虚拟运行时间(vruntime)

(1)作用

  • 量化任务的“公平性”,用于在红黑树中排序任务(选择 vruntime 最小的任务运行)。
  • 任务运行时,vruntime 会增长,增长速率与权重成反比(高权重任务增长更慢,低权重任务增长更快)。

(2)计算方式

  • 公式
    vruntime += (实际运行时间 Δt) × (NICE_0_LOAD / 任务权重)
    
    • NICE_0_LOADnice=0 的基准权重(1024)。
    • 示例
      • nice=0 的任务运行 10ms:vruntime += 10 × (1024 / 1024) = 10
      • nice=5(权重=335)的任务运行 10ms:vruntime += 10 × (1024 / 335) ≈ 30.6

(3)调度决策

  • CFS 维护一个按 vruntime 排序的红黑树,每次 pick_next_task 选择 vruntime 最小的任务执行。
  • 公平性体现
    • 高权重任务 vruntime 增长慢,能更频繁地被调度。
    • 低权重任务 vruntime 增长快,减少 CPU 占用。

3. 最小虚拟时间(min_vruntime)

(1)作用

  • 跟踪 CFS 运行队列(cfs_rq)中所有任务的最小 vruntime,用于:
    1. 新任务的初始化:新创建的或唤醒的任务的 vruntime 会被设置为 min_vruntime,避免“饿死”新任务。
    2. 跨 CPU 迁移:任务迁移时,vruntime 会根据目标 CPU 的 min_vruntime 调整,维持全局公平。

(2)更新规则

  • 当任务被加入/移除运行队列时,min_vruntime 会更新:
    min_vruntime = max(min_vruntime, 当前任务的 vruntime);
    
  • 示例
    • 若队列中任务的最小 vruntime 是 1000,新任务的 vruntime=1200,则 min_vruntime 仍为 1000。
    • 若新任务的 vruntime=800,则 min_vruntime 更新为 800。

(3)对任务迁移的影响

  • 当任务从一个 CPU 迁移到另一个 CPU 时,其 vruntime 会按目标 CPU 的 min_vruntime 调整:
    vruntime_new = vruntime_old - min_vruntime_old + min_vruntime_new
    
    • 防止任务因迁移获得不公平的优势或劣势。

4. 三者的协同工作流程

场景示例

  1. 任务 A(nice=0)和任务 B(nice=5)启动

    • 权重:A=1024,B=335。
    • 初始 vruntime 均为 0(或 min_vruntime)。
  2. 调度周期 20ms

    • 任务 A 运行:10msvruntime += 10 × (1024/1024) = 10
    • 任务 B 运行:10msvruntime += 10 × (1024/335) ≈ 30.6
  3. 下一轮调度

    • 任务 A 的 vruntime=10,任务 B 的 vruntime=30.6 → 选择 vruntime 更小的 A 运行。
  4. 长期效果

    • 任务 A 获得约 75% CPU 时间,任务 B 获得约 25%(符合权重比例)。

5. 关键数据结构

(1)task_struct 相关字段

struct task_struct {struct sched_entity se;      // 调度实体// ...
};struct sched_entity {u64 vruntime;               // 虚拟运行时间struct load_weight load;     // 负载权重(含 weight 字段)// ...
};

(2)cfs_rq 运行队列

struct cfs_rq {u64 min_vruntime;           // 当前队列的最小 vruntimestruct rb_root tasks_timeline; // 按 vruntime 排序的红黑树// ...
};

6. 总结

概念作用关键影响
负载权重决定任务获取 CPU 时间的比例nice 值 → 权重 → 时间分配
虚拟运行时间量化任务的“公平性”并排序红黑树中选择 vruntime 最小的任务
最小虚拟时间维护全局公平性,处理新任务和迁移防止新任务饿死,调整迁移任务的公平性

CFS 通过这三者的配合,实现了:

  • 按权重分配 CPU 时间(高 nice 任务少占 CPU)。
  • 动态公平调度vruntime 确保长期公平)。
  • 多核一致性min_vruntime 处理跨 CPU 迁移)。

相关文章:

  • Js 判断浏览器cookie 是否启用
  • 2025盘古石初赛WP
  • linux 开发小技巧之git增加指令别名
  • 路由策略和策略路由的区别以及配置案例
  • 用Python绘制动态彩色ASCII爱心:技术深度与创意结合
  • FHE与后量子密码学
  • 解决使用宝塔Linux部署前后端分离项目遇到的问题
  • Nakama:让游戏与应用更具互动性和即时性
  • 相机Camera日志分析之八:高通Camx HAL架构opencamera三级日志详解及关键字
  • spring中的@Inject注解详情
  • linux perf top分析系统性能
  • 深入解析JavaScript变量作用域:var、let、const全攻略
  • [架构之美]从零开始整合Spring Boot与Maven(十五)
  • upload-labs靶场通关详解:第四关
  • 【typenum】 0 配置文件(Cargo.toml)
  • SemanticSplitterNodeParser 和 Sentence-BERT 的区别和联系是什么
  • 前端敏感数据处理指南_JavaScript 加密方法全解析
  • 警惕C#版本差异多线程中的foreach陷阱
  • AI 驱动的开发工具
  • PyTorch API 7 - TorchScript、hub、矩阵、打包、profile
  • 中方就乌克兰危机提出新倡议?外交部:中方立场没有变化
  • 首批证券公司科创债来了!拟发行规模超160亿元
  • 乡村快递取件“跑腿费”屡禁不止?云南元江县公布举报电话
  • 教育部、国家发改委联合启动实施教师教育能力提升工程
  • 戴维·珀杜宣誓就任美国驻华大使
  • 公募基金行业迎系统性变革:基金公司业绩差必须少收费