Fork me on GitHub
侧边栏

Linux 内核中sched_prio_to_weight转换关系

在 Linux 内核调度器中,sched_prio_to_weight 是一个非常关键的数组,用于把「静态优先级(nice 值)」映射为调度权重(weight)。

调度器(CFS:Completely Fair Scheduler)不是直接比较 nice 值,而是通过权重控制各任务获得的 CPU 时间比例。


一、sched_prio_to_weight 的定义位置

代码位置(以常见版本为例):

// kernel/sched/core.c 或 kernel/sched/fair.c
const int sched_prio_to_weight[40] = {
    /* -20 */ 88761, 71755, 56483, 46273, 36291,
    /* -15 */ 29154, 23254, 18705, 14949, 11916,
    /* -10 */ 9548, 7620, 6100, 4904, 3906,
    /*  -5 */ 3121, 2501, 1991, 1586, 1277,
    /*   0 */ 1024, 820, 655, 526, 423,
    /*   5 */ 335, 272, 215, 172, 137,
    /*  10 */ 110, 87, 70, 56, 45,
    /*  15 */ 36, 29, 23, 18, 15,
};

其中索引为 prio - MAX_RT_PRIO,对应 nice 值范围 [-20, +19]


二、转换关系说明

Linux 的 nice 值范围是 -20 ~ +19

  • 数值越小(更负),优先级越高;
  • 数值越大,优先级越低。

调度器通过以下公式近似计算各任务的运行时间份额:

1

任务的虚拟运行时间增量:

2

这意味着:

  • weight 大 → vruntime 增加得慢 → 任务更容易再次被调度;
  • weight 小 → vruntime 增加快 → 任务更少获得 CPU。

三、weight 之间的比例规律

每相邻两个 nice 值之间的 weight 比例大约为 1.25 倍(也就是每增加 1 个 nice,权重乘以 0.8 左右)。

换句话说:

3

即:

  • nice -20 → 88761
  • nice -19 → 71755(约等于 88761 / 1.24)
  • nice 0 → 1024
  • nice +19 → 15

这样可以保证:

  • nice 值差 10,对应权重比例约为 10 倍;
  • nice 值差 20,对应权重比例约为 100 倍。

四、权重的数学近似公式

虽然内核中使用表格查表,但有一个经验公式近似表达:

4

举例:

nice weight(近似) 实际表中值
-20 1024×(1.25)^20 ≈ 88366 88761
0 1024 1024
+19 1024×(1.25)^(-19) ≈ 16.4 15

非常接近。


五、调度比例示例

假设两个任务:

  • A:nice = 0 → weight = 1024
  • B:nice = +5 → weight = 335

则 CPU 时间分配比:
5

即 A 得到约 75%,B 得到约 25% CPU 时间。


六、与其他表的关系

除了 sched_prio_to_weight 外,还有:

const u32 sched_prio_to_wmult[40];

它存放的是 2^32 / weight 的结果,用于加速计算(避免除法)。


七、总结

Nice 权重 (Weight) 相对比 (相对 nice=0) CPU 时间占比
-20 88761 86.7x 极高
-10 9548 9.3x
0 1024 1x 标准
+10 110 0.107x
+19 15 0.014x 极低

posted @ 2025-11-02 08:45  yooooooo  阅读(8)  评论(0)    收藏  举报