简介

本文介绍Inferno工具。Inferno基于SimplePerf,用于为Android native应用生成火焰图(Flame graph)——如SurfaceFlinger。As we all known,Android中常用PerfettoProfiler的method trace来生成应用层的火焰图,但是它们对native进程束手无策。Inferno正是为此而生,可以将Inferno看成是支持native app的Profiler.MethodTracer。

Inferno最初被设计和制造出来是用于分析和优化SurfaceFlinger的性能的,目前能针对任何native app工作,以及非native app的native部分。正如同Profiler,Inferno生成native code的flame graph,并同样的生成可视化的HTML。

下图展示InfernoSurfaceFlinger生成的火焰图的示例。

原理

Inferno的原理和结构都非常简单,因为不论是执行method trace的组件还是生成火焰图的组件都是调用已有的优秀的工具。

Inferno利用SimplePerfSimplePerf是Android基于Linux的perf实现的)实现对Process的method trace,包含方法跟踪、栈帧展开、堆栈回溯等实现method trace的核心功能均调用SimplePerf实现。SimplePerf产生的perf.data会被Inferno从设备中拉取并分析——主要是合并堆栈、计算耗时占比。

然后,Inferno像大多数性能工具一样通过火焰图组件生成统计数据。只要将数据喂入,数据的生成过程并不要求额外精力投入。

因此,Inferno结构非常简单。Simple,but not easy。

火焰图的作者是性能工具大师Brendan Greggkai设计并开发的。他是享誉全球的大能。Wiki

使用

Inferno基于Simpleperf开发,与Simpleperf位于同一个目录。system/extras/simpleperf/scripts/inferno

  • Default:抓取SurfaceFlinger
    1
    ./inferno.py
    前文阐述过,Inferno最初设计用于SurfaceFlinger Performance,因此不带任何参数启动时,Inferno会抓取SurfaceFlinger的method trace(实际上是Simpleperf抓的)然后生成火焰图到HTML。

不带参数时默认抓取SF: Default option is: "-np surfaceflinger -f 6000 -t 10".

上文提到method trace实质上由Simpleperf处理,对应参数如下。其中-p指定pid,-f为method sample的频率(method trace普遍有两种实现,一个是trace,一个是sample。Trace类似与在函数进入和退出都打点记录,Sample类似于每隔一小段时间就使用暂停分析栈帧、栈展开/栈回溯分析的方式——采样),-f指定的就是采样频率。–duration指定本次采集10秒。

1
/data/local/tmp/simpleperf record -o /data/local/tmp/perf.data --call-graph fp -f 6000 --duration 10 -p 451
  • 参数
    1. -du dwarf_unwinding,使用dwarf来实现栈回溯。缺省情况下是使用fp来实现回溯的
    2. -e events,使用发生了events来触发采样(sample),缺省情况下是sample
    3. -f fr,指定采样频率
    4. -np NATIVE_PROGRAM,指定目标进程且目标进程必须是native进程
    5. -p App,指定目标进程且目标进程必须是Android应用进程
    6. –pid PID,等同于np,仅形式是pid
    7. –record_file 指定Simpleperf的记录文件,(Simpleperf)缺省为perf.data
    8. –system_wide 抓整个系统的,而不是单个进程;这个参数可以把系统里面所有进程都生成火焰图(实际上,就是给Simpleperf传递-a参数,要求Simpleperf全局抓)
    9. -t 抓多久
    10. -o 指定输出HTML的路径
    11. –one-flamegraph 缺省时,目标进程的所有线程是单独分开、各自生成各自的火焰图。该选项将所有线程都合并进一张火焰图
    12. –kallsyms 指定kernel的符号方便解析
    13. –symfs 指定进程的符号方便解析
    14. –show_art_frames 采样ART的栈帧
    15. -c {hot,dso,legacy}, –color {hot,dso,legacy};指定生成的图标样式。三个样式差异在于,hot是最适合performance的、耗时多少决定了长度的模式;legacy记录调用的函数,没有热力分析功能;dso记录callsite

发现性能瓶颈(bottleneck):寻高原期定CPU cost——find CPU cost by looking for plateaus

  1. 按照火焰图的基本功能,可以直接找在火焰尖的较长的平台,它们基本都很有可能是性能热点。

    火焰图就是看从下往上看的哪个函数占据的宽度最大,只要有“平顶”,就表示该函数可能存在性能问题

  2. 颜色颜色为橙色或者红色表示性能消耗较大。注意!通常来说,原生的常规的火焰图的颜色不代表任何意义,它的颜色是为了好区分每一行而随机选择的,不具备任何意义。不过Inferno做了些修改,颜色越深,如红色和橙色,表示消耗越大。Inferno的火焰图的颜色不是没有意义的。

参考

  1. Google Inferno