专栏首页Linuxer的专栏宋宝华:火焰图 全局视野的 Linux 性能剖析
原创

宋宝华:火焰图 全局视野的 Linux 性能剖析

作者简介:宋宝华,他有10几年的Linux开发经验。他长期在大型企业担任一线工程师和系统架构师,编写大量的Linux代码,并负责在gerrit上review其他同事的代码。Barry Song是Linux的活跃开发者,是某些内核版本的最活跃开发者之一(如https://lwn.net/Articles/395961/https://lwn.net/Articles/429912/ ),也曾是一ARM SoC系列在Linux mainline的maintainer。

他也是china-pub等据销售评估的2008年度“十大畅销经典”,“十佳原创精品”图书《Linux设备驱动开发详解》的作者和《Essential Linux Device Driver》的译者。同时书写了很多技术文章,是51CTO 2012年度“十大杰出IT博客”得主及51CTO、CSDN的专家博主。他也热衷于开源项目,正在开发LEP(Linux Easy Profiling,http://www.linuxep.com )项目,并希望获得更多人的参与和帮助。

什么是火焰图

火焰图(Flame Graph)是由Linux性能优化大师Brendan Gregg发明的,和所有其他的trace和profiling方法不同的是,Flame Graph以一个全局的视野来看待时间分布,它从底部往顶部,列出所有可能的调用栈。其他的呈现方法,一般只能列出单一的调用栈或者非层次化的时间分布。

我最快乐的童年时代,每逢冬天,尤其是春节的时候,和一家人围坐在火堆旁边烤火。这已经成为最美好的回忆,其实人生追求的快乐非常简单。火焰图的火焰首先来自于根,然后以火苗的形式往上面窜。可以把从靠近地面的根到顶上的每个火苗,想想成一个调用栈。由于火苗有很多根,这正好也和现实生活中程序的执行逻辑相似。

以典型的分析CPU时间花费到哪个函数的on-cpu火焰图为例来展开。

CPU火焰图中的每一个方框是一个函数,方框的长度,代表了它的执行时间,所以越宽的函数,执行越久。火焰图的楼层每高一层,就是更深一级的函数被调用,最顶层的函数,是叶子函数。

火焰图的生成过程是:

  1. 先trace系统,获取系统的profiling数据
  2. 用脚本来绘制

系统的profiling数据获取,可以选择最流行的perf record,而后把采集的数据进行加工处理,绘制为火焰图。其中第二步的绘制火焰图的脚本程序,通过如下方式获取:

git clone https://github.com/brendangregg/FlameGraph

火焰图案例

废话不多说,直接从最简单的例子开始说起。talk is cheap, show you the cde,代码如下:

c()
{
    for(int i=0;i<1000;i++);
}
b()
{
    for(int i=0;i<1000;i++);
    c();
}
a()
{
    for(int i=0;i<1000;i++);
    b();
}

则这三个函数,在火焰图中呈现的样子为:

a()的2/3的时间花在b()上面,而b()的1/3的时间花在c()上面。很多个这样的a->b->c的火苗堆在一起,就构成了火焰图。

进一步理解火焰图的最好方法仍然是通过一个实际的案例,下面的程序创建2个线程,两个线程的handler都是thread_fun(),之后thread_fun()调用fun_a()、fun_b()、fun_c(),而fun_a()又会调用fun_d():

/*
 * One example to demo flamegraph
 *
 * Copyright (c) Barry Song
 *
 * Licensed under GPLv2
 */

#include <pthread.h>

func_d()
{
    int i;
    for(i=0;i<50000;i++);
}

func_a()
{
    int i;
    for(i=0;i<100000;i++);
    func_d();
}

func_b()
{
    int i;
    for(i=0;i<200000;i++);
}

func_c()
{
    int i;
    for(i=0;i<300000;i++);
}

void* thread_fun(void* param)
{
    while(1) {
        int i;
        for(i=0;i<100000;i++);

        func_a();
        func_b();
        func_c();
    }
}

int main(void)
{
    pthread_t tid1,tid2;
    int ret;

    ret=pthread_create(&tid1,NULL,thread_fun,NULL);
    if(ret==-1){
        ...
    }

    ret=pthread_create(&tid2,NULL,thread_fun,NULL);
    ...

    if(pthread_join(tid1,NULL)!=0){
        ...
    }

    if(pthread_join(tid2,NULL)!=0){
        ...
    }

    return 0;
}

先看看不用火焰图的缺点在哪里。

如果不用火焰图,我们也可以用类似perf top这样的工具分析出来CPU时间主要花费在哪里了:

$gcc exam.c -pthread
$./a.out&
$sudo perf top

perf top的显示结果如下:

perf top提示出来了fun_a()、fun_b()、fun_c(), fun_d(),thread_func()这些函数内部的代码是CPU消耗大户,但是它缺乏一个全局的视野,我们无法看出全局的调用栈,也弄不清楚这些函数之间的关系。火焰图则不然,我们用下面的命令可以生成火焰图(以root权限运行):

perf record -F 99 -a -g -- sleep 60
perf script | ./stackcollapse-perf.pl > out.perf-folded
./flamegraph.pl out.perf-folded > perf-kernel.svg

上述程序捕获系统的行为60秒钟,最后调用flamegraph.pl生成一个火焰图perf-kernel.svg,用看图片的工具就可以打开这个svg。

上述火焰图显示出了a.out中,thread_func()、func_a()、func_b()、fun_c()和func_d()的时间分布。

从上述火焰图可以看出,虽然thread_func()被两个线程调用,但是由于thread_func()之前的调用栈是一样的,所以2个线程的thread_func()调用是合并为同一个方框的。

更深阅读

除了on-cpu的火焰图以外,off-cpu的火焰图,对于分析系统堵在IO、SWAP、取得锁方面的帮助很大,有利于分析系统在运行的时候究竟在等待什么,系统资源之间的彼此伊伴。

比如,下面的火焰图显示,nginx的吞吐能力上不来的很多程度原因在于sem_wait()等待信号量。

上图摘自Yichun Zhang (agentzh)的《Introduction to offCPU Time Flame Graphs》。

关于火焰图的更多细节和更多种火焰图各自的功能,可以访问: http://www.brendangregg.com/flamegraphs.html

本文来自 Linuxerr 微信公众号

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • IT皇冠上的明珠! Linux 操作系统学习看过来!

    操作系统堪称是IT皇冠上的明珠,Linux阅码场专注Linux操作系统内核研究, 它的文章云集了国内众多知名企业一线工程师的心得,畅销著作有《linux设备驱动...

    编程珠玑
  • 火焰图:全局视野的Linux性能剖析

    火焰图(Flame Graph)是由Linux性能优化大师Brendan Gregg发明的,和所有其他的trace和profiling方法不同的是,Flame ...

    Linux阅码场
  • 火焰图:全局视野的Linux性能剖析

    日常的工作中,会收到一堆CPU使用率过高的告警邮件,遇到某台服务的CPU被占满了,这时候我们就要去查看是什么进程将服务器的CPU资源占用满了。通常我们会通过to...

    公众号: 云原生生态圈
  • 宋宝华: 用off-cpu火焰图进行Linux性能分析

    在《宋宝华:火焰图:全局视野的Linux性能剖析》一文中,我们主要看了on-cpu火焰图,理解了系统的CPU的走向的分析。但是,很多时候,单纯地看on-cpu的...

    Linux阅码场
  • 牛逼的Linux性能剖析—perf

    系统级性能优化通常包括两个阶段:性能剖析(performance profiling)和代码优化。性能剖析的目标是寻找性能瓶颈,查找引发性能问题的原因及热点代码...

    刘盼
  • 高性能:LEP (LINUX EASY PROFILING) 工具介绍

    然后,在右上方的框内,输入 lepd所在的节点地址 (我们这里还是 10.10.11.11)

    二狗不要跑
  • Linux用户态进程的内存管理

    上一篇我们了解了内存在内核态是如何管理的,本篇文章我们一起来看下内存在用户态的使用情况,如果上一篇文章说是内核驱动工程师经常面对的内存管理问题,那本篇就是应用工...

    刘盼
  • 【Node.js丨主题周】理解perf 与火焰图

    火焰图(Flame Graph)看起来就像一团跳动的火焰,因此得名,它可以将 CPU 的使用情况可视化,使我们直观地了解到程序的性能瓶颈。我们通常要结合操作系统...

    博文视点Broadview
  • 程序员精进之路:性能调优利器--火焰图

    ? 作者:厉辉,腾讯 CSIG 后台开发工程师 本文主要分享火焰图使用技巧,介绍 systemtap 的原理机制,如何使用火焰图快速定位性能问题原因,同时加深...

    腾讯技术工程官方号
  • Linux内核书籍

    《Linux设备驱动》   --  也就是我们所说的LDD3了; 适合一定基础的人阅读,深入学习Linux不可或缺的知识; 《UNIX环境高级编程》 这本书并不...

    233333
  • E3 2017正式开幕:怒刷存在感的任天堂,这次终于来真的了

    VRPinea
  • 用CPI火焰图分析Linux性能问题

    本文中若有任何疏漏错误,有任何建议和意见,请回复内核月谈微信公众号,或通过 oliver.yang at linux.alibaba.com 反馈。

    Linux阅码场
  • 清明豫见“黄河之礼” 老家河南牵手腾讯打开黄河文化宝箱

    ? 凝聚数字科技创意力量,点亮河南黄河流域的非遗光彩。 以“传承文明、拥抱春天”为主题的清明文化盛典——2021中国(开封)清明文化节于4月3日盛大开幕。“老...

    腾讯文旅
  • cpu分析利器 — async-profiler

    async-profiler是一款采集分析java性能的工具,翻译一下github上的项目介绍:

    龟仙老人
  • LEP 与负载均衡 : 以 PCDUINO 实际案例来使用LEP提高网络带宽

    这篇文章的内容涉及用 LEP 监控 PCDUINO 3nano 电路板网络流量,观察负载均衡 IDLE、 IRQ 和 SoftIRQ,以及用 RPS/RFS ...

    Linuxer
  • Linux问题故障定位,看这一篇就够了

    有时候会遇到一些疑难杂症,并且监控插件并不能一眼立马发现问题的根源。这时候就需要登录服务器进一步深入分析问题的根源。那么分析问题需要有一定的技术经验积累,并且有...

    我在鹅厂做安全
  • NodeJS 性能优化之 CPU 看图篇

    作为前端出身的 NodeJS 开发者们,产生共鸣的那就是如何能够直观且快速发现性能瓶颈,能够像调试前端的 JS 代码那样可视化,堆栈化,接下来我们就针对常见的 ...

    web爱好者
  • 火焰图性能调优记

    最近手头开发维护的一个辅助小工具经常接到投诉可用性问题, 于是抽时间定位了下, 一看吓一跳, 起初不起眼的一个组件的日志量直接翻了两个数量级。 这怎么吃得消 !

    黄奕坤
  • 红毯阵容太豪华!阿里星球上线发布会引来半个文娱圈

    5月18日,中国互联网音乐生力军阿里音乐集团首次召开大型产品上线发布会,隆重对外推介颠覆性粉丝娱乐交互平台——阿里星球。这是阿里音乐继上个月正式推出阿里星球体验...

    罗超频道

扫码关注云+社区

领取腾讯云代金券