perf sched查看调度延迟与唤醒延迟

ftrace也可以通过内核中固定的调度相关的tracepoint来记录线程的调度信息,但ftrace只能抓到调度的原始数据(线程调度切换流程),不能提供统计分析功能,只提供类似于perf sched script的功能。perf也是利用内核中固定的调度trcepoint,但perf提供了统计分析功能,例如可以查看某段时间内的最大调度延迟等信息。

1,perf sched record

2,perf sched latency --sort max

如下某段时间内的最大调度延迟是0.467ms,调度性能较好。

所谓调度延迟的意义:

如下图所示,线程sh(pid=17030)在.918368秒被别的线程唤醒(被唤醒在本核 或者 通过IPI唤醒到其他核 或者 若其他核正处于idle就设置NEED_RESCHED,这样idle线程就能POLLING到有新线程要在本核上运行),sched_wakeup表示该线程被唤醒在cpu2上,即将该线程放在cpu2上的运行队列上(对于normal线程来说是CFS调度算法的红黑树的叶子节点上,根据vruntime的值)。.948070秒的sched_switch表示该线程17030才真正在cpu2上投入运行。

即线程17030从ready(放在cpu2运行队列的那个时刻)到开始真正在cpu2上运行的延迟是29ms。

存在调度延迟的原因可能是:

1,即使线程17030的vruntime比cpu2上正在运行线程的vruntime小,但两者的vruntime差值小于最小抢占粒度(sched_wakeup_granularity_ns),所以不能立即抢占cpu2上当前正在运行的线程。要等当前线程运行结束,即在cpu2的时钟中断或中断返回用户空间(通用centos内核不支持内核抢占)时判断是否选择新线程(可能是线程17030,也可能不是)运行。

2,cpu2上当前正在运行的线程已运行的时间还小于最小运行时间(sched_min_granularity_ns),为防止切换太频繁,所以不能切换17030线程运行;

3,唤醒抢占的feature关闭,即sched_features中WAKEUP_PREEMPT特性关闭,不允许唤醒抢占

另外可通过如下命令图形化的查看线程调度情况:

perf timechart record #几秒后ctl+c中断

perf timechart #结果输出在当前目录中,文件output.svg

perf sched timehist

perf sched timehist 功能是 Linux 4.10 加入的(https://lore.kernel.org/patchwork/patch/738098/),可以按照调度事件查看任务等待被唤醒的时间 (wait time) 和任务从被唤醒之后到运行态的调度延迟,同时也显示了调度延迟。wait time可以查看线程因等待资源(锁,信号量等)而消耗的时间:

也可以加更多的参数,如:perf sched timehist -MVw,可以显示更多的选项。

其他可查看:

http://www.brendangregg.com/blog/2017-03-16/perf-sched.html

发布了158 篇原创文章 · 获赞 115 · 访问量 37万+

猜你喜欢

转载自blog.csdn.net/yiyeguzhou100/article/details/102809576