前言
一直想用 gperftools
做一下性能方面的尝试,之前一直忙着开发,目前已经到了后期,忙里抽闲亲自操作一遍,从安装到分析做个简单的记录,以便后续拿来直接用。
gperftools 是什么
gperftools 是Google开发的用来进行代码性能分析工具,其实他是一系列高性能多线程 malloc() 实现的集合,同时添加了一些精巧的性能分析工具。
使用gperftools工具可以通过采样的方式生成上面这种图形化的代码性能分析结果,便于我们分析程序性能瓶颈。
使用方法
C++程序按照代码插桩的方式引入了gperftools工具,不过这个工具需要单独安装,为了生成图形化的分析结果,还需要安装一些依赖库,下面简述以下使用功能步骤。
安装工具
安装编译所需基础软件
1
sudo apt install autoconf automake libtool
安装graphviz,用于图形化显示分析结果
1
sudo apt install graphviz
安装libunwind, 这个库提供了可用于分析程序调用栈的 API
1
2
3
4
5
6
7
8
9cd /tmp
wget https://github.com/libunwind/libunwind/releases/download/v1.6.2/libunwind-1.6.2.tar.gz
tar -zxvf libunwind-1.6.2.tar.gz
cd libunwind-1.6.2
./configure
make -j4
sudo make install
cd /tmp
rm -rf libunwind-1.6.2.tar.gz libunwind-1.6.2安装gperftools
1
2
3
4
5
6
7
8
9cd /tmp
wget https://github.com/gperftools/gperftools/releases/download/gperftools-2.10/gperftools-2.10.tar.gz
tar -zxvf gperftools-2.10.tar.gz
cd gperftools-2.10
./configure
make -j4
sudo make install
cd ~
rm -rf gperftools-2.10.tar.gz gperftools-2.10刷新动态装入程序所需的链接和缓存文件
1
sudo ldconfig
代码插桩引入工具
代码修改
主要在源程序中引入头文件,并且在待测试逻辑前后添加启动分析和结束分析的语句就行了,对于服务类程序,因为要一直运行,可以通过kill
信号通知来开启和关闭性能分析。
关键代码
1 |
|
完整示例
1 |
|
编译链接
编译时我们需要将 profiler
库和 libunwind
库链接到可执行程序,如果使用 cmake
来构建,那么 CMakeLists 文件中的语句为:
1 | target_link_libraries(${PROJECT_NAME} profiler unwind) |
启动分析程序
正常启动游戏服务器,通过ps命令查找到要分析的进程id,比如查找到demoserver的进程是
7217
1
2$ ps -ef | grep demoserver
demo 7217 1 22 21:51 ? 00:00:18 ./demoserver-d通过kill命令传递自定义信号
10
的方式启动和关闭分析程序,第一次运行命令是启动,第二次运行相同的命令是关闭,两次命令之间是分析的时间段1
$ kill -10 7217
关闭分析程序之后,会在可执行程序所在目录生成
cpp_demo.porf
文件,可以使用下面命令将结果图形化1
2
3
4$ pprof --pdf demoserver cpp_demo.prof > demoserver.pdf
Using local file demoserver.
Using local file cpp_demo.prof.
Dropping nodes with <= 1 samples; edges with <= 0 abs(samples)最终生成的
demoserver.pdf
文件就是我们要用的分析结果,如文章开头所示。
数据分析
上面提到了生成pdf图,其实可以生成txt文本的,只要修改生成选项就可以,比如像这样:
1 | # pprof --text demoserver cpp_demo.prof |
上述文本数据每行包含6列数据,依次为:
- 分析样本数量(不包含其他函数调用)
- 分析样本百分比(不包含其他函数调用)
- 目前为止的分析样本百分比(不包含其他函数调用)
- 分析样本数量(包含其他函数调用)
- 分析样本百分比(包含其他函数调用)
- 函数名(或者类名+方法名)
样本数量相当于消耗的CPU时间,整个函数消耗的CPU时间相当于包括函数内部其他函数调用所消耗的CPU时间,如果是分析最上面的pdf图,每个节点代表一个函数,包含2~3行数据:
gperftools
是可以通过采样的方式进行代码性能分析工具,可生成图形化结果便于我们分析程序性能瓶颈- 待分析程序中引入
gperftools
非常方便,但是需要单独安装这个工具 - 程序引入时只需要添加头文件,在目标位置插入
ProfilerStart("cpp_demo.prof");
和ProfilerStop();
语句即可 - 对于服务类程序通常不会直接结束,可以通过
kill
命令传递信号的方式来启动和关闭分析程序
可能终于有一天 刚好遇见爱情
可能永远在路上 有人奋斗前行
可能一切的可能 相信才有可能
可能拥有过梦想 才能叫做青春2023-4-19 23:22:53