宋宝华: 用off-cpu火焰图进行Linux性能分析

在《宋宝华:火焰图:全局视野的Linux性能剖析》一文中,我们主要看了on-cpu火焰图,理解了系统的CPU的走向的分析。但是,很多时候,单纯地看on-cpu的情况(什么代码在耗费CPU),并不能解决性能问题,因为有时候性能差的原因瓶颈不一定在CPU上面,而是在off-cpu的时间,比如:

  1. 进程进入系统调用执行io动作,io动作的延迟

  2. 进程等待mutex锁的时间

  3. 内存被交换,swap的时间

  4. 内存不够的时候,执行直接内存回收的时间

  5. 进程被抢占调度走、或者时间片用完被调度走的时间(runqueue太大)

等等等。

基本上,off-cpu的状态图如下(图片来自:

http://www.brendangregg.com/offcpuanalysis.html)

比如一个http服务器,登录的用户多了后,如果普遍觉得上网慢,瓶颈可能出现在网络慢、硬盘读取慢、mutex竞争等。这种情况下,on-cpu可能不是问题,主要的问题可能是在off-cpu的部分了。off-cpu分析,对性能问题的调优也至关重要。

下面我们写一个最简单的程序

gcc编译它,可以获得a.out。假设我们追求的性能目标是:每秒钟打印地hello world越多越好,证明这个进程越能服务更多的打印请求。当然现实生活中的程序比这个要复杂1万倍,但是这个例子不妨碍我们说明原理。

实验环境:

Ubuntu-18.10,内核版本4.18,apt install安装bpfcc-tools - tools for BPF Compiler Collection (BCC)工具包,以及git clone了

https://github.com/brendangregg/FlameGraph

下面我们采集一个它的off-cpu时间:

barry@barryUbuntu:~$ sudo offcputime-bpfcc -K -p `pgrep -nx a.out`

Tracing off-CPU time (us) of PID 5593 by kernel stack... Hit Ctrl-C to end.

按下ctrl-c停下来后,我们看到2个主要的off-cpu的栈回溯是:

一个发生在usleep()调用的hrtimer_nanosleep -> do_nanosleep系统调用;一个发生在printf()的时候,进入sys_write系统调用后,tty_write的n_tty_write等待一个mutex的代码上面。

这个时候,我们可以进一步查看Linux内核的代码

https://lxr.missinglinkelectronics.com/linux+v4.18/drivers/tty/n_tty.c#L2285

我们认为延迟应该是出现在这个地方:

....

所以,如果我们想实现每秒打印hello world尽可能多的目标,显然应该删除那个usleep,以及分析为什么这个mutex_lock要这么久,看看内核里面有无优化的空间。

如果我们想绘制系统在运行上述a.out进程的时候的off-cpu火焰图,我们可以先采集调度数据30秒,得到out.stacks:

sudo offcputime-bpfcc -df -p `pgrep -nx a.out` 30 > out.stacks

接下来,我们进入clone下来的FlameGraph项目目录,用flamegraph.pl绘制火焰图:

./flamegraph.pl --color=io --title="Off-CPU Time Flame Graph" --countname=us ~/out.stacks > output.svg

用看图片的工具打开output.svg:

从图上也可以看到,off-cpu的2个主要原因一个是nanosleep,一个是write系统调用进入后n_tty_write里面要拿mutex。

点击write的路径,可以局部放大这部分栈回溯:

与我们前面的文本分析的结果是一致的。如果我们想优化性能,一个是可以消除usleep,第二个是分析为什么mutex_lock要等这么久,有什么空间可以提高。

本文是一篇关于off-cpu火焰图的入门引导性文章,如果您对此感兴趣,可以进一步参考:

http://www.brendangregg.com/offcpuanalysis.html

(完)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值