.. SPDX-License-Identifier: GPL-2.0 .. include:: ../disclaimer-zh_CN.rst :Original: Documentation/scheduler/sched-stats.rst :翻译: å”艺舟 Tang Yizhou <tangyeechou@gmail.com> ============== è°ƒåº¦å™¨ç»Ÿè®¡æ•°æ® ============== 第15版schedstats去掉了sched_yield的一些计数器:yld_exp_empty,yld_act_empty å’Œyld_both_empty。在其它方é¢å’Œç¬¬14版完全相åŒã€‚ 第14版schedstats包括对sched_domains(译注:调度域)的支æŒï¼Œè¯¥ç‰¹æ€§è¿›å…¥å†…æ ¸ 主线2.6.20,ä¸è¿‡è¿™ä¸€ç‰ˆschedstats与2.6.13-2.6.19å†…æ ¸çš„ç‰ˆæœ¬12çš„ç»Ÿè®¡æ•°æ®æ˜¯å®Œå…¨ 相åŒçš„ï¼ˆå†…æ ¸æœªå‘布第13版)。有些计数器按æ¯ä¸ªè¿è¡Œé˜Ÿåˆ—统计是更有æ„义的,其它则 按æ¯ä¸ªè°ƒåº¦åŸŸç»Ÿè®¡æ˜¯æ›´æœ‰æ„义的。注æ„,调度域(以åŠå®ƒä»¬çš„附属信æ¯ï¼‰ä»…åœ¨å¼€å¯ CONFIG_SMP的机器上是相关的和å¯ç”¨çš„。 在第14版schedstatä¸ï¼Œæ¯ä¸ªè¢«åˆ—出的CPU至少会有一级域统计数æ®ï¼Œä¸”很å¯èƒ½æœ‰ä¸€ä¸ª 以上的域。在这个实现ä¸ï¼ŒåŸŸæ²¡æœ‰ç‰¹åˆ«çš„åå—ï¼Œä½†æ˜¯ç¼–å·æœ€é«˜çš„域通常在机器上所有的 CPU上仲è£å¹³è¡¡ï¼Œè€Œdomain0是最紧密èšç„¦çš„域,有时仅在一对CPUä¹‹é—´è¿›è¡Œå¹³è¡¡ã€‚æ¤æ—¶ï¼Œ 没有任何体系结构需è¦3层以上的域。域统计数æ®ä¸çš„ç¬¬ä¸€ä¸ªå—æ®µæ˜¯ä¸€ä¸ªä½å›¾ï¼Œè¡¨æ˜Žå“ªäº› CPUå—该域的影å“。 è¿™äº›å—æ®µæ˜¯è®¡æ•°å™¨ï¼Œè€Œä¸”åªèƒ½é€’å¢žã€‚ä½¿ç”¨è¿™äº›å—æ®µçš„程åºå°†éœ€è¦ä»ŽåŸºçº¿è§‚测开始,然åŽåœ¨ åŽç»æ¯ä¸€ä¸ªè§‚测ä¸è®¡ç®—出计数器的å˜åŒ–ã€‚ä¸€ä¸ªèƒ½ä»¥è¿™ç§æ–¹å¼å¤„ç†å…¶ä¸å¾ˆå¤šå—段的perl脚本 å¯è§ http://eaglet.pdxhosts.com/rick/linux/schedstat/ 请注æ„ï¼Œä»»ä½•è¿™æ ·çš„è„šæœ¬éƒ½å¿…é¡»æ˜¯ç‰¹å®šäºŽç‰ˆæœ¬çš„ï¼Œæ”¹å˜ç‰ˆæœ¬çš„主è¦åŽŸå› æ˜¯è¾“å‡ºæ ¼å¼çš„å˜åŒ–。 对于那些希望编写自己的脚本的人,å¯ä»¥å‚考这里æè¿°çš„å„ä¸ªå—æ®µã€‚ CPUç»Ÿè®¡æ•°æ® ----------- cpu<N> 1 2 3 4 5 6 7 8 9 ç¬¬ä¸€ä¸ªå—æ®µæ˜¯sched_yield()的统计数æ®ï¼š 1) sched_yield()被调用了#次 接下æ¥çš„三个是schedule()的统计数æ®ï¼š 2) è¿™ä¸ªå—æ®µæ˜¯ä¸€ä¸ªè¿‡æ—¶çš„æ•°ç»„过期计数,在O(1)调度器ä¸ä½¿ç”¨ã€‚为了ABI兼容性, 我们ä¿ç•™äº†å®ƒï¼Œä½†å®ƒæ€»æ˜¯è¢«è®¾ç½®ä¸º0。 3) schedule()被调用了#次 4) 调用schedule()导致处ç†å™¨å˜ä¸ºç©ºé—²äº†#次 接下æ¥çš„两个是try_to_wake_up()的统计数æ®ï¼š 5) try_to_wake_up()被调用了#次 6) 调用try_to_wake_up()导致本地CPU被唤醒了#次 接下æ¥çš„ä¸‰ä¸ªç»Ÿè®¡æ•°æ®æè¿°äº†è°ƒåº¦å»¶è¿Ÿï¼š 7) 本处ç†å™¨è¿è¡Œä»»åŠ¡çš„æ€»æ—¶é—´ï¼Œå•使˜¯çº³ç§’ 8) 本处ç†å™¨ä»»åŠ¡ç‰å¾…è¿è¡Œçš„æ—¶é—´ï¼Œå•使˜¯çº³ç§’ 9) 本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ä¸ªå—æ®µæ˜¯load_balance()函数的å„个统计数æ®ï¼ŒæŒ‰ç©ºé—²ç±»åž‹åˆ†ç»„(空闲, ç¹å¿™ï¼Œæ–°ç©ºé—²ï¼‰ï¼š 1) 当CPU空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨äº†#次 2) 当CPU空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œä½†æ˜¯å‘çŽ°è´Ÿè½½æ— éœ€ å‡è¡¡#次 3) 当CPU空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œè¯•图è¿ç§»1个或更多 任务且失败了#次 4) 当CPU空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œå‘现ä¸å‡è¡¡ï¼ˆå¦‚果有) #次 5) 当CPU空闲时,pull_task()在这个调度域ä¸è¢«è°ƒç”¨#次 6) 当CPUç©ºé—²æ—¶ï¼Œå°½ç®¡ç›®æ ‡ä»»åŠ¡æ˜¯çƒç¼“å˜çжæ€ï¼Œpull_task()ä¾ç„¶è¢«è°ƒç”¨#次 7) 当CPU空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œæœªèƒ½æ‰¾åˆ°æ›´ç¹å¿™çš„ 队列#次 8) 当CPUç©ºé—²æ—¶ï¼Œåœ¨è°ƒåº¦åŸŸä¸æ‰¾åˆ°äº†æ›´ç¹å¿™çš„队列,但未找到更ç¹å¿™çš„调度组 #次 9) 当CPUç¹å¿™æ—¶ï¼Œsched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨äº†#次 10) 当CPUç¹å¿™æ—¶ï¼Œsched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œä½†æ˜¯å‘çŽ°è´Ÿè½½æ— éœ€ å‡è¡¡#次 11) 当CPUç¹å¿™æ—¶ï¼Œsched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œè¯•图è¿ç§»1个或更多 任务且失败了#次 12) 当CPUç¹å¿™æ—¶ï¼Œsched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œå‘现ä¸å‡è¡¡ï¼ˆå¦‚果有) #次 13) 当CPUç¹å¿™æ—¶ï¼Œpull_task()在这个调度域ä¸è¢«è°ƒç”¨#次 14) 当CPUç¹å¿™æ—¶ï¼Œå°½ç®¡ç›®æ ‡ä»»åŠ¡æ˜¯çƒç¼“å˜çжæ€ï¼Œpull_task()ä¾ç„¶è¢«è°ƒç”¨#次 15) 当CPUç¹å¿™æ—¶ï¼Œsched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œæœªèƒ½æ‰¾åˆ°æ›´ç¹å¿™çš„ 队列#次 16) 当CPUç¹å¿™æ—¶ï¼Œåœ¨è°ƒåº¦åŸŸä¸æ‰¾åˆ°äº†æ›´ç¹å¿™çš„队列,但未找到更ç¹å¿™çš„调度组 #次 17) 当CPU新空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨äº†#次 18) 当CPU新空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œä½†æ˜¯å‘çŽ°è´Ÿè½½æ— éœ€ å‡è¡¡#次 19) 当CPU新空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œè¯•图è¿ç§»1个或更多 任务且失败了#次 20) 当CPU新空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œå‘现ä¸å‡è¡¡ï¼ˆå¦‚果有) #次 21) 当CPU新空闲时,pull_task()在这个调度域ä¸è¢«è°ƒç”¨#次 22) 当CPUæ–°ç©ºé—²æ—¶ï¼Œå°½ç®¡ç›®æ ‡ä»»åŠ¡æ˜¯çƒç¼“å˜çжæ€ï¼Œpull_task()ä¾ç„¶è¢«è°ƒç”¨#次 23) 当CPU新空闲时,sched_balance_rq()在这个调度域ä¸è¢«è°ƒç”¨ï¼Œæœªèƒ½æ‰¾åˆ°æ›´ç¹å¿™çš„ 队列#次 24) 当CPUæ–°ç©ºé—²æ—¶ï¼Œåœ¨è°ƒåº¦åŸŸä¸æ‰¾åˆ°äº†æ›´ç¹å¿™çš„队列,但未找到更ç¹å¿™çš„调度组 #次 接下æ¥çš„3ä¸ªå—æ®µæ˜¯active_load_balance()函数的å„个统计数æ®ï¼š 25) active_load_balance()被调用了#次 26) active_load_balance()被调用,试图è¿ç§»1个或更多任务且失败了#次 27) active_load_balance()被调用,æˆåŠŸè¿ç§»äº†#次任务 接下æ¥çš„3ä¸ªå—æ®µæ˜¯sched_balance_exec()函数的å„个统计数æ®ï¼š 28) sbe_cntä¸å†è¢«ä½¿ç”¨ 29) sbe_balancedä¸å†è¢«ä½¿ç”¨ 30) sbe_pushedä¸å†è¢«ä½¿ç”¨ 接下æ¥çš„3ä¸ªå—æ®µæ˜¯sched_balance_fork()函数的å„个统计数æ®ï¼š 31) sbf_cntä¸å†è¢«ä½¿ç”¨ 32) sbf_balancedä¸å†è¢«ä½¿ç”¨ 33) sbf_pushedä¸å†è¢«ä½¿ç”¨ 接下æ¥çš„3ä¸ªå—æ®µæ˜¯try_to_wake_up()函数的å„个统计数æ®ï¼š 34) 在这个调度域ä¸è°ƒç”¨try_to_wake_up()唤醒任务时,任务在调度域ä¸ä¸€ä¸ª 和上次è¿è¡Œä¸åŒçš„æ–°CPU上è¿è¡Œäº†#次 35) 在这个调度域ä¸è°ƒç”¨try_to_wake_up()唤醒任务时,任务被è¿ç§»åˆ°å‘生唤醒 çš„CPU次数为#ï¼Œå› ä¸ºè¯¥ä»»åŠ¡åœ¨åŽŸCPU是冷缓å˜çŠ¶æ€ 36) 在这个调度域ä¸è°ƒç”¨try_to_wake_up()唤醒任务时,引å‘被动负载å‡è¡¡#次 /proc/<pid>/schedstat --------------------- schedstatsè¿˜æ·»åŠ äº†ä¸€ä¸ªæ–°çš„/proc/<pid>/schedstatæ–‡ä»¶ï¼Œæ¥æä¾›ä¸€äº›è¿›ç¨‹çº§çš„ 相åŒä¿¡æ¯ã€‚这个文件ä¸ï¼Œæœ‰ä¸‰ä¸ªå—段与该进程相关: 1) 在CPU上è¿è¡ŒèŠ±è´¹çš„æ—¶é—´(å•使˜¯çº³ç§’) 2) 在è¿è¡Œé˜Ÿåˆ—上ç‰å¾…的时间(å•使˜¯çº³ç§’) 3) 在CPU上è¿è¡Œäº†#个时间片 å¯ä»¥å¾ˆå®¹æ˜“地编写一个程åºï¼Œåˆ©ç”¨è¿™äº›é¢å¤–çš„å—æ®µæ¥æŠ¥å‘Šä¸€ä¸ªç‰¹å®šçš„进程或一组进程在 调度器ç–ç•¥ä¸‹çš„è¡¨çŽ°å¦‚ä½•ã€‚è¿™æ ·çš„ç¨‹åºçš„一个简å•版本å¯åœ¨ä¸‹é¢çš„链接找到 http://eaglet.pdxhosts.com/rick/linux/schedstat/v12/latency.c