英语

调度器统计

schedstats 的第 16 版更改了 'enum cpu_idle_type' 中定义的顺序,这更改了 show_schedstat() 中 [CPU_MAX_IDLE_TYPES] 列的顺序。特别是 CPU_IDLE 和 __CPU_NOT_IDLE 的位置互换了。数组的大小不变。

schedstats 的第 15 版删除了某些 sched_yield 的计数器:yld_exp_empty、yld_act_empty 和 yld_both_empty。除此之外,它与第 14 版相同。

schedstats 的第 14 版包含对调度域的支持,该支持在 2.6.20 中进入主线内核,尽管它与 2.6.13-2.6.19 内核中的第 12 版(第 13 版从未发布内核)的统计数据相同。一些计数器对于每个运行队列更有意义;其他计数器对于每个域更有意义。请注意,域(及其关联信息)仅在利用 CONFIG_SMP 的机器上才相关且可用。

在 schedstat 的第 14 版中,列出的每个 cpu 至少有一个域统计级别,并且可能有多个域。在此实现中,域没有特定的名称,但编号最高的域通常仲裁机器上所有 cpu 之间的平衡,而 domain0 是最紧凑的域,有时仅在 cpu 对之间进行平衡。目前,没有架构需要超过三个域级别。域统计中的第一个字段是一个位图,指示该域影响哪些 cpu。

这些字段是计数器,并且只会增加。使用这些字段的程序需要从基线观察开始,然后在每次后续观察时计算计数器的变化。一个 perl 脚本可以对许多字段执行此操作,网址为

请注意,任何此类脚本都必须是特定于版本的,因为更改版本的主要原因是输出格式的更改。对于那些希望编写自己的脚本的人,这里描述了这些字段。

CPU 统计

cpu<N> 1 2 3 4 5 6 7 8 9

第一个字段是 sched_yield() 统计信息

  1. sched_yield() 被调用的次数

接下来的三个是 schedule() 统计信息

  1. 此字段是 O(1) 调度程序中使用的旧数组过期计数字段。我们保留它以实现 ABI 兼容性,但它始终设置为零。

  2. schedule() 被调用的次数

  3. schedule() 使处理器空闲的次数

接下来的两个是 try_to_wake_up() 统计信息

  1. try_to_wake_up() 被调用的次数

  2. try_to_wake_up() 被调用以唤醒本地 cpu 的次数

接下来的三个是描述调度延迟的统计信息

  1. 此处理器上任务花费的所有运行时间总和(以纳秒为单位)

  2. 此处理器上任务花费的所有等待运行的时间总和(以纳秒为单位)

  3. 在此 cpu 上运行的时间片数

域统计

为所描述的每个 cpu 的每个域生成一个。(请注意,如果未定义 CONFIG_SMP,则使用任何域,并且这些行不会出现在输出中。)

domain<N> <cpumask> 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36

第一个字段是一个位掩码,指示此域在哪些 cpu 上运行。

接下来的 24 个是 sched_balance_rq() 的各种统计信息,按空闲类型(空闲、忙碌和新空闲)分组

  1. 在此域中,当 cpu 空闲时,sched_balance_rq() 被调用的次数

  2. 在此域中,当 cpu 空闲时,sched_balance_rq() 检查但发现负载不需要平衡的次数

  3. 在此域中,当 cpu 空闲时,sched_balance_rq() 尝试移动一个或多个任务但失败的次数

  4. 在此域中,当 cpu 空闲时,每次调用 sched_balance_rq() 时发现的不平衡总和(如果有)

  5. 在此域中,当 cpu 空闲时,pull_task() 被调用的次数

  6. 在此域中,即使目标任务在空闲时缓存热,pull_task() 被调用的次数

  7. 在此域中,当 cpu 空闲时,sched_balance_rq() 被调用但未找到更忙队列的次数

  8. 在此域中,当 cpu 空闲时,发现更忙队列但未找到更忙组的次数

  9. 在此域中,当 cpu 忙碌时,sched_balance_rq() 被调用的次数

  10. 在此域中,当 cpu 忙碌时,sched_balance_rq() 检查但发现负载不需要平衡的次数

  11. 在此域中,当 cpu 忙碌时,sched_balance_rq() 尝试移动一个或多个任务但失败的次数

  12. 在此域中,当 cpu 忙碌时,每次调用 sched_balance_rq() 时发现的不平衡总和(如果有)

  13. 在此域中,当 cpu 忙碌时,pull_task() 被调用的次数

  14. 在此域中,即使目标任务在忙碌时缓存热,pull_task() 被调用的次数

  15. 在此域中,当 cpu 忙碌时,sched_balance_rq() 被调用但未找到更忙队列的次数

  16. 在此域中,当 cpu 忙碌时,发现更忙队列但未找到更忙组的次数

  17. 在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 被调用的次数

  18. 在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 检查但发现负载不需要平衡的次数

  19. 在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 尝试移动一个或多个任务但失败的次数

  20. 在此域中,当 cpu 刚变为空闲时,每次调用 sched_balance_rq() 时发现的不平衡总和(如果有)

  21. 在此域中,当 cpu 刚变为空闲时,pull_task() 被调用的次数

  22. 在此域中,即使目标任务在刚变为空闲时缓存热,pull_task() 被调用的次数

  23. 在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 被调用但未找到更忙队列的次数

  24. 在此域中,当 cpu 刚变为空闲时,发现更忙队列但未找到更忙组的次数

接下来的三个是 active_load_balance() 统计信息

  1. active_load_balance() 被调用的次数

  2. active_load_balance() 尝试移动任务但失败的次数

  3. active_load_balance() 成功移动任务的次数

接下来的三个是 sched_balance_exec() 统计信息

  1. 未使用 sbe_cnt

  2. 未使用 sbe_balanced

  3. 未使用 sbe_pushed

接下来的三个是 sched_balance_fork() 统计信息

  1. 未使用 sbf_cnt

  2. 未使用 sbf_balanced

  3. 未使用 sbf_pushed

接下来的三个是 try_to_wake_up() 统计信息

  1. 在此域中,try_to_wake_up() 唤醒的上次在此域中不同 cpu 上运行的任务的次数

  2. 在此域中,try_to_wake_up() 将任务移动到唤醒 cpu 的次数,因为它无论如何在其自身的 cpu 上都是缓存冷的

  3. 在此域中,try_to_wake_up() 启动被动平衡的次数

/proc/<pid>/schedstat

schedstats 还添加了一个新的 /proc/<pid>/schedstat 文件,以包含每个进程级别的一些相同信息。此文件中有三个字段,与该进程相关联

  1. 在 cpu 上花费的时间(以纳秒为单位)

  2. 在运行队列上等待的时间(以纳秒为单位)

  3. 在此 cpu 上运行的时间片数

可以轻松编写程序来利用这些额外的字段,以报告特定进程或一组进程在调度程序的策略下的表现如何。此类程序的简单版本可在以下网址找到