0001 .. SPDX-License-Identifier: GPL-2.0
0002 .. include:: ../disclaimer-zh_CN.rst
0003
0004 :Original: Documentation/scheduler/sched-stats.rst
0005
0006 :翻译:
0007
0008 唐艺舟 Tang Yizhou <tangyeechou@gmail.com>
0009
0010 ==============
0011 调度器统计数据
0012 ==============
0013
0014 第15版schedstats去掉了sched_yield的一些计数器:yld_exp_empty,yld_act_empty
0015 和yld_both_empty。在其它方面和第14版完全相同。
0016
0017 第14版schedstats包括对sched_domains(译注:调度域)的支持,该特性进入内核
0018 主线2.6.20,不过这一版schedstats与2.6.13-2.6.19内核的版本12的统计数据是完全
0019 相同的(内核未发布第13版)。有些计数器按每个运行队列统计是更有意义的,其它则
0020 按每个调度域统计是更有意义的。注意,调度域(以及它们的附属信息)仅在开启
0021 CONFIG_SMP的机器上是相关的和可用的。
0022
0023 在第14版schedstat中,每个被列出的CPU至少会有一级域统计数据,且很可能有一个
0024 以上的域。在这个实现中,域没有特别的名字,但是编号最高的域通常在机器上所有的
0025 CPU上仲裁平衡,而domain0是最紧密聚焦的域,有时仅在一对CPU之间进行平衡。此时,
0026 没有任何体系结构需要3层以上的域。域统计数据中的第一个字段是一个位图,表明哪些
0027 CPU受该域的影响。
0028
0029 这些字段是计数器,而且只能递增。使用这些字段的程序将需要从基线观测开始,然后在
0030 后续每一个观测中计算出计数器的变化。一个能以这种方式处理其中很多字段的perl脚本
0031 可见
0032
0033 http://eaglet.pdxhosts.com/rick/linux/schedstat/
0034
0035 请注意,任何这样的脚本都必须是特定于版本的,改变版本的主要原因是输出格式的变化。
0036 对于那些希望编写自己的脚本的人,可以参考这里描述的各个字段。
0037
0038 CPU统计数据
0039 -----------
0040 cpu<N> 1 2 3 4 5 6 7 8 9
0041
0042 第一个字段是sched_yield()的统计数据:
0043
0044 1) sched_yield()被调用了#次
0045
0046 接下来的三个是schedule()的统计数据:
0047
0048 2) 这个字段是一个过时的数组过期计数,在O(1)调度器中使用。为了ABI兼容性,
0049 我们保留了它,但它总是被设置为0。
0050 3) schedule()被调用了#次
0051 4) 调用schedule()导致处理器变为空闲了#次
0052
0053 接下来的两个是try_to_wake_up()的统计数据:
0054
0055 5) try_to_wake_up()被调用了#次
0056 6) 调用try_to_wake_up()导致本地CPU被唤醒了#次
0057
0058 接下来的三个统计数据描述了调度延迟:
0059
0060 7) 本处理器运行任务的总时间,单位是纳秒
0061 8) 本处理器任务等待运行的时间,单位是纳秒
0062 9) 本CPU运行了#个时间片
0063
0064 域统计数据
0065 ----------
0066
0067 对于每个被描述的CPU,和它相关的每一个调度域均会产生下面一行数据(注意,如果
0068 CONFIG_SMP没有被定义,那么*没有*调度域被使用,这些行不会出现在输出中)。
0069
0070 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
0071
0072 第一个字段是一个位掩码,表明该域在操作哪些CPU。
0073
0074 接下来的24个字段是load_balance()函数的各个统计数据,按空闲类型分组(空闲,
0075 繁忙,新空闲):
0076
0077
0078 1) 当CPU空闲时,load_balance()在这个调度域中被调用了#次
0079 2) 当CPU空闲时,load_balance()在这个调度域中被调用,但是发现负载无需
0080 均衡#次
0081 3) 当CPU空闲时,load_balance()在这个调度域中被调用,试图迁移1个或更多
0082 任务且失败了#次
0083 4) 当CPU空闲时,load_balance()在这个调度域中被调用,发现不均衡(如果有)
0084 #次
0085 5) 当CPU空闲时,pull_task()在这个调度域中被调用#次
0086 6) 当CPU空闲时,尽管目标任务是热缓存状态,pull_task()依然被调用#次
0087 7) 当CPU空闲时,load_balance()在这个调度域中被调用,未能找到更繁忙的
0088 队列#次
0089 8) 当CPU空闲时,在调度域中找到了更繁忙的队列,但未找到更繁忙的调度组
0090 #次
0091 9) 当CPU繁忙时,load_balance()在这个调度域中被调用了#次
0092 10) 当CPU繁忙时,load_balance()在这个调度域中被调用,但是发现负载无需
0093 均衡#次
0094 11) 当CPU繁忙时,load_balance()在这个调度域中被调用,试图迁移1个或更多
0095 任务且失败了#次
0096 12) 当CPU繁忙时,load_balance()在这个调度域中被调用,发现不均衡(如果有)
0097 #次
0098 13) 当CPU繁忙时,pull_task()在这个调度域中被调用#次
0099 14) 当CPU繁忙时,尽管目标任务是热缓存状态,pull_task()依然被调用#次
0100 15) 当CPU繁忙时,load_balance()在这个调度域中被调用,未能找到更繁忙的
0101 队列#次
0102 16) 当CPU繁忙时,在调度域中找到了更繁忙的队列,但未找到更繁忙的调度组
0103 #次
0104 17) 当CPU新空闲时,load_balance()在这个调度域中被调用了#次
0105 18) 当CPU新空闲时,load_balance()在这个调度域中被调用,但是发现负载无需
0106 均衡#次
0107 19) 当CPU新空闲时,load_balance()在这个调度域中被调用,试图迁移1个或更多
0108 任务且失败了#次
0109 20) 当CPU新空闲时,load_balance()在这个调度域中被调用,发现不均衡(如果有)
0110 #次
0111 21) 当CPU新空闲时,pull_task()在这个调度域中被调用#次
0112 22) 当CPU新空闲时,尽管目标任务是热缓存状态,pull_task()依然被调用#次
0113 23) 当CPU新空闲时,load_balance()在这个调度域中被调用,未能找到更繁忙的
0114 队列#次
0115 24) 当CPU新空闲时,在调度域中找到了更繁忙的队列,但未找到更繁忙的调度组
0116 #次
0117
0118 接下来的3个字段是active_load_balance()函数的各个统计数据:
0119
0120 25) active_load_balance()被调用了#次
0121 26) active_load_balance()被调用,试图迁移1个或更多任务且失败了#次
0122 27) active_load_balance()被调用,成功迁移了#次任务
0123
0124 接下来的3个字段是sched_balance_exec()函数的各个统计数据:
0125
0126 28) sbe_cnt不再被使用
0127 29) sbe_balanced不再被使用
0128 30) sbe_pushed不再被使用
0129
0130 接下来的3个字段是sched_balance_fork()函数的各个统计数据:
0131
0132 31) sbf_cnt不再被使用
0133 32) sbf_balanced不再被使用
0134 33) sbf_pushed不再被使用
0135
0136 接下来的3个字段是try_to_wake_up()函数的各个统计数据:
0137
0138 34) 在这个调度域中调用try_to_wake_up()唤醒任务时,任务在调度域中一个
0139 和上次运行不同的新CPU上运行了#次
0140 35) 在这个调度域中调用try_to_wake_up()唤醒任务时,任务被迁移到发生唤醒
0141 的CPU次数为#,因为该任务在原CPU是冷缓存状态
0142 36) 在这个调度域中调用try_to_wake_up()唤醒任务时,引发被动负载均衡#次
0143
0144 /proc/<pid>/schedstat
0145 ---------------------
0146 schedstats还添加了一个新的/proc/<pid>/schedstat文件,来提供一些进程级的
0147 相同信息。这个文件中,有三个字段与该进程相关:
0148
0149 1) 在CPU上运行花费的时间(单位是纳秒)
0150 2) 在运行队列上等待的时间(单位是纳秒)
0151 3) 在CPU上运行了#个时间片
0152
0153 可以很容易地编写一个程序,利用这些额外的字段来报告一个特定的进程或一组进程在
0154 调度器策略下的表现如何。这样的程序的一个简单版本可在下面的链接找到
0155
0156 http://eaglet.pdxhosts.com/rick/linux/schedstat/v12/latency.c