OpenHarmony上使用火焰图

描述

一般来说,我们发现程序卡顿,排除其他程序问题和硬件问题,那一定是自身程序中某个位置运行时,消耗的时间过长导致。

性能问题分析方式

要找到耗时的代码段,才能有针对性的进行优化,那第一个问题就是如何找到耗时的代码段。

首先我们能想到,在程序中可能存在问题的地方,加入计算时间差的代码,然后不断缩小范围,找到最终耗时的点。

#include 
uint64_t GetTimeStampUS()
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000000 + tv.tv_usec;
}
.....
void FuncA()
{
    uint64_t t1 = GetTimeStampUS();
    FuncB();
    uint64_t t2 = GetTimeStampUS();
    FuncC();
    uint64_t t3 = GetTimeStampUS();
    printf("FuncB cost : %llu,FuncC cost : %llu
",t2-t1,t3-t2);
}

 

这种方式最终也能解决问题,但是会有一些缺点:

①对于大型项目来说,要经过大量的【编译,执行验证,添加代码】迭代,消耗大量时间。

②排查到问题后,需要把测试代码删除,下次排查时又要重新添加代码。

③通过查看文本 log 方式分析,不直观。 下面我们看看如何使用 bytrace 来分析问题。  

在 OpenHarmony 中使用 Bytrace

①在 BUILD.gn 中添加对 bytrace 的依赖:

 

    external_deps = [
        "bytrace_standard:bytrace_core",
    ]
   

 

②添加头文件:

 

#include 
   

 

③添加打点代码:

 

void FuncA() {
    StartTrace(BYTRACE_TAG_GRAPHIC_AGP, "funcB");
    funcB();
    FinishTrace(BYTRACE_TAG_GRAPHIC_AGP);
}
   

 

代码部分完成了,编译更新到开发板,然后使用下面命令来抓取 log:

 

hdc shell bytrace -t 10 -b 8192 graphic > ~/logs/log.ftrace
    参数说明: -t 10:从运行命令行开始,抓取 10 秒时间(非必要参数,默认 5 秒) -b 8192:使用 8192kb(8M) 内存来缓存数据(非必要参数,默认 2048kb) graphic:抓取 graphic 类型的 trace,对应上面代码中的 BYTRACE_TAG_GRAPHIC_AGP 最后把抓取的结果保存到 log.ftrace 这个文件中(文件后缀名非限定,txt 也行),通过文本编辑器打开查看。 到目前为止,看起来跟加入时间差代码的方式差不多,还是打点看 log,接着往下看。  

 

优化打点

把 bytrace 的打点代码封装起来,xtrace.h:

 

#include 
#include "bytrace.h"

class XTrace
{
public:
    XTrace(std::string fname);
    ~XTrace();
};
   

 

xtrace.cpp:

 

XTrace::XTrace(std::string fname)
{
    StartTrace(BYTRACE_TAG_ZCAMERA, fname);
}

XTrace::~XTrace()
{
    FinishTrace(BYTRACE_TAG_ZCAMERA);
}
   

 

这样我们用起来就更方便了:

 

void FuncB(){
    XTrace trace1(__func__);
}

void FuncA(){
{
    XTrace trace1(__func__);
    FuncB();
    {
        XTrace trace2(__func__);
        FuncC();
    }
}
    函数开始,创建 XTrace 对象时,构造函数调用 StartTrace。函数结束或离开作用域,栈中的对象会自动释放,析构函数调用 FinishTrace。 当然这种方式也可以用于时间差打点。  

 

可视化看 log

链接如下:

 

https://ui.perfetto.dev
 

 

这个网站需要科学方法访问,首次访问后有了缓存,后续就可以离线访问了。

代码

我这边把网页保存下来了,在本地开 web 服务,通过 127.0.0.1 也可以使用。 首先点击左上角 Open trace file 打开 log.ftrace,右边会显示出函数调用的火焰图,点击其中一个函数,在下方可以看到准确的执行时间。

基本操作:

键盘 w,s:时间轴缩放

键盘 a,d:左右移动

可视化看时间轴就非常直观了,横条越长,消耗时间越多。

OpenHarmony 对 bytrace 的集成

我们在 OpenHarmony 使用 bytrace,除了以上的便利以外,最重要的是 OpenHarmony 的代码中已经大量使用了 bytrace。

下面是我整理的已经集成 bytrace 的模块:

代码

代码

对于以上模块的性能问题,我们就能直接使用对应 tag 来抓取。  

其他

      对于一个较大的模块代码,我们需要理解他的执行流程,函数调用关系,会比较头疼。

所以我编写了一个脚本,扫描所有的 .cpp 文件,在所有函数开头自动添加:

 

XTrace xxx(__func__);
  在可视化界面分析 log,可以清晰的看到函数执行的,不同的线程,函数的调用栈,能快速的梳理代码的执行流程。 第四点中的图,是我对 foundation/ace/ace_engine/frameworks 这个目录下 2000 个左右 cpp 文件中的函数全部添加 XTrace 后,得到的应用启动流程火焰图。 

 

审核编辑:汤梓红

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分