LINUX性能监测工具-02-侵入式

LINUX性能监测工具-02-侵入式

1.介绍

侵入式的性能检测工具,顾名思义即需要修改代码才能使用。

在商业领域有OProf,由于是收费的,因此应用并不广泛,我本人也没用过,因此不再介绍。

在开源领域有gprof(g for GNU),gcc编译器自带了该工具。虽说不用显式的修改源代码(编译时添加-pg选项即可),但编译出来的程序不能直接用于生产运行,因此也算是侵入式的。

gprof虽然是免费的,还有GNU官方背书,但有几个致命缺陷:一是不支持多线程应用,只能分析主线程性能;二是不支持跟踪动态库中的函数调用情况。

今天给大家介绍一个g开头的性能分析工具-google performance tools,功能完备,支持多线程下的性能分析,工具链也比较完善,能生成火焰图等直观炫酷的结果展示形式。

2.安装

在Redhat下使用如下命令安装(包含火焰图等图形生成工具):

yum install gperftools
yum install pprof
yum install graphviz
git clone https://github.com/brendangregg/FlameGraph.git

在Ubuntu下使用如下命令安装:

apt-get install google-perftools
git clone https://github.com/gperftools/gperftools.git
apt-get install libgoogle-perftools-dev
git clone https://github.com/brendangregg/FlameGraph.git

3.使用

a) 源码及编译

在源代码中应该包含如下几个要素:

  • 包含头文件:gperftools/profiler.h
  • 准备开始搜集性能数据时,调用:ProfilerStart(“gperf_capture.prof”)(参数是保存性能数据的文件路径)
  • 如果需要分析线程的性能数据,在需要分析的线程中调用:ProfilerRegisterThread()
  • 结束分析时,调用ProfilerStop()(注意,用户只有调用了该接口,性能数据文件中才会有数据,程序正常或异常退出时,性能数据文件中不会自动写入数据)

下面展示了一个简单的例子:

#include <gperftools/profiler.h>
#include <pthread.h>

// g++ -o gperf_test gperf_test.cpp -lpthread -lprofiler

void* thread_func_1(void* p_arg)
{
    ProfilerRegisterThread();

    long loop = 4000000000;
    while(loop--)
        ;

    return NULL;
}

void* thread_func_2(void* p_arg)
{
    ProfilerRegisterThread();

    long loop = 4000000000;
    while(loop--)
        ;

    return NULL;
}

int main()
{
    ProfilerStart("gperf_capture.prof");

    pthread_t thr_id_1, thr_id_2;
    pthread_create(&thr_id_1, NULL, thread_func_1, NULL);
    pthread_create(&thr_id_2, NULL, thread_func_2, NULL);
    pthread_join(thr_id_1, NULL);
    pthread_join(thr_id_2, NULL);

    ProfilerStop();

    return 0;
}


我们启动了两个线程,在每个线程中各跑一个空循环,循环结束后退出。

注意:编译的时候,要加上-lprofiler选项。

b) 运行生成性能分析文件

添加-lprofiler编译链接生成程序后,还需要实际运行一次,才能生成性能数据文件。

c) 图形化展示

使用pprof脚本,可以基于上面生成的性能数据文件生成图形文件:

./gperftools/src/pprof ./gperf_test gperf_capture.prof --svg >func_call.svg

注意:Redhat系统下,调用pprof不用那么麻烦,直接pprof就行

生成的图形效果如下:

可以看到,两个线程各占了大约一半的执行时间。

除了上面的这种函数调用图外,还能用FlameGraph工具生成炫酷的火焰图:

风格1:

./gperftools/src/pprof ./gperf_test gperf_capture.prof --collapsed > func_call.cbt
./FlameGraph/flamegraph.pl func_call.cbt > flame_1.svg

效果如下:

风格2:

./gperftools/src/pprof ./gperf_test gperf_capture.prof --collapsed > func_call.cbt
./FlameGraph/flamegraph.pl --invert --color aqua func_call.cbt > flame_2.svg

效果如下:

区别是展示调用栈的方向不同。

注意:将上述svg图形用浏览器打开,鼠标移动到对应的函数时,屏幕会显示关于该函数的全部信息。

由于我们的例子程序太过简单,因此展示的效果不太震撼,给大家看看其他的几个例子:

4.参考链接

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注