调度器统计¶
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() 统计信息
sched_yield() 被调用的次数
接下来的三个是 schedule() 统计信息
此字段是 O(1) 调度程序中使用的旧数组过期计数字段。我们保留它以实现 ABI 兼容性,但它始终设置为零。
schedule() 被调用的次数
schedule() 使处理器空闲的次数
接下来的两个是 try_to_wake_up() 统计信息
try_to_wake_up() 被调用的次数
try_to_wake_up() 被调用以唤醒本地 cpu 的次数
接下来的三个是描述调度延迟的统计信息
此处理器上任务花费的所有运行时间总和(以纳秒为单位)
此处理器上任务花费的所有等待运行的时间总和(以纳秒为单位)
在此 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() 的各种统计信息,按空闲类型(空闲、忙碌和新空闲)分组
在此域中,当 cpu 空闲时,sched_balance_rq() 被调用的次数
在此域中,当 cpu 空闲时,sched_balance_rq() 检查但发现负载不需要平衡的次数
在此域中,当 cpu 空闲时,sched_balance_rq() 尝试移动一个或多个任务但失败的次数
在此域中,当 cpu 空闲时,每次调用 sched_balance_rq() 时发现的不平衡总和(如果有)
在此域中,当 cpu 空闲时,pull_task() 被调用的次数
在此域中,即使目标任务在空闲时缓存热,pull_task() 被调用的次数
在此域中,当 cpu 空闲时,sched_balance_rq() 被调用但未找到更忙队列的次数
在此域中,当 cpu 空闲时,发现更忙队列但未找到更忙组的次数
在此域中,当 cpu 忙碌时,sched_balance_rq() 被调用的次数
在此域中,当 cpu 忙碌时,sched_balance_rq() 检查但发现负载不需要平衡的次数
在此域中,当 cpu 忙碌时,sched_balance_rq() 尝试移动一个或多个任务但失败的次数
在此域中,当 cpu 忙碌时,每次调用 sched_balance_rq() 时发现的不平衡总和(如果有)
在此域中,当 cpu 忙碌时,pull_task() 被调用的次数
在此域中,即使目标任务在忙碌时缓存热,pull_task() 被调用的次数
在此域中,当 cpu 忙碌时,sched_balance_rq() 被调用但未找到更忙队列的次数
在此域中,当 cpu 忙碌时,发现更忙队列但未找到更忙组的次数
在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 被调用的次数
在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 检查但发现负载不需要平衡的次数
在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 尝试移动一个或多个任务但失败的次数
在此域中,当 cpu 刚变为空闲时,每次调用 sched_balance_rq() 时发现的不平衡总和(如果有)
在此域中,当 cpu 刚变为空闲时,pull_task() 被调用的次数
在此域中,即使目标任务在刚变为空闲时缓存热,pull_task() 被调用的次数
在此域中,当 cpu 刚变为空闲时,sched_balance_rq() 被调用但未找到更忙队列的次数
在此域中,当 cpu 刚变为空闲时,发现更忙队列但未找到更忙组的次数
接下来的三个是 active_load_balance() 统计信息
active_load_balance() 被调用的次数
active_load_balance() 尝试移动任务但失败的次数
active_load_balance() 成功移动任务的次数
接下来的三个是 sched_balance_exec() 统计信息
未使用 sbe_cnt
未使用 sbe_balanced
未使用 sbe_pushed
接下来的三个是 sched_balance_fork() 统计信息
未使用 sbf_cnt
未使用 sbf_balanced
未使用 sbf_pushed
接下来的三个是 try_to_wake_up() 统计信息
在此域中,try_to_wake_up() 唤醒的上次在此域中不同 cpu 上运行的任务的次数
在此域中,try_to_wake_up() 将任务移动到唤醒 cpu 的次数,因为它无论如何在其自身的 cpu 上都是缓存冷的
在此域中,try_to_wake_up() 启动被动平衡的次数
/proc/<pid>/schedstat¶
schedstats 还添加了一个新的 /proc/<pid>/schedstat 文件,以包含每个进程级别的一些相同信息。此文件中有三个字段,与该进程相关联
在 cpu 上花费的时间(以纳秒为单位)
在运行队列上等待的时间(以纳秒为单位)
在此 cpu 上运行的时间片数
可以轻松编写程序来利用这些额外的字段,以报告特定进程或一组进程在调度程序的策略下的表现如何。此类程序的简单版本可在以下网址找到