Linux C++程序进行性能分析工具gprof使用入门

性能分析工具

软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键。这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是要重点测试版本的性能表现和稳定性的。对于软件测试过程中发现的性能问题,如何定位有很多的方法。基本的方法可能是开发者对代码进行review,或者是使用一些工具对代码进行性能分析。常见的性能分析tuning工具有哪些呢?下面两篇文章做了详细的总结:

在我工作中主要是关于Linux C++程序代码的性能分析,gprof是可用于Linux C++代码性能profiling的工具之一,本文主要讲讲我对gprof的学习和使用过程。

Gprof的基本原理

gprof能够让你知道你的代码哪些地方是比较耗时的,哪些函数是被调用次数很多的,并且能够让你一目了然的看到函数与函数之间的调用关系。gprof是gcc/g++编译器支持的一种性能诊断工具。只要在编译时加上-pg选项,编译器就会在编译程序时在每个函数的开头加一个mcount函数调用,在每一个函数调用之前都会先调用这个mcount函数,在mcount中会保存函数的调用关系图和函数的调用时间和被调次数等信息。最终在程序退出时保存在gmon.out文件中,需要注意的是程序必须是正常退出或者通过exit调用退出,因为只要在exit()被调用时才会触发程序写gmon.out文件。

那么,gprof的使用方法主要以下三步:

  • 会用-pg参数编译程序
  • 运行程序,并正常退出
  • 查看gmon.out文件

Gprof使用实例

  1. #include<iostream>
  2. using namespace std;
  3. int add(int a, int b)
  4. {
  5. return a+b;
  6. }
  7. int sub(int a, int b)
  8. {
  9. return a-b;
  10. }
  11. int call ()
  12. {
  13. std::cout << add(1,2) << std::endl;
  14. std::cout << sub(2,4) << std::endl;
  15. }
  16. int main()
  17. {
  18. int a=1, b=2;
  19. cout << add(a,b) << endl;
  20. for (int i=0; i<10000; i++)
  21. call();
  22. return 0;
  23. }

使用g++编译并加上-pg参数:

  1. g++ -o hello hello_grof.cpp -pg -g

得到可执行文件,我们可以使用readelf查看一下它的符号表里和没有-pg时编译的有啥不同:readelf -r ./hello和readelf -r ./hello_normal得出的结果对比。

左边为有-pg参数编译的结果。可以看出多了三个函数符号_mcount, __monstartup, _mcleanup都是和gprof相关的调用。

使用gdb调试hello程序,在mcount函数中打断点也可以看到其调用关系,在add函数执行前先调用mcount函数:

接下来运行程序./hello,会在当前目录下生成gmon.out文件。使用gprof查看文件信息:

  1. gprof -b ./hello gmon.out

得到如下输出:

  1. Flat profile:
  2. Each sample counts as 0.01 seconds.
  3. no time accumulated
  4. %   cumulative   self              self     total
  5. time   seconds   seconds    calls  Ts/call  Ts/call  name
  6. 0.00      0.00     0.00    10001     0.00     0.00  add(int, int)
  7. 0.00      0.00     0.00    10000     0.00     0.00  sub(int, int)
  8. 0.00      0.00     0.00    10000     0.00     0.00  call()
  9. 0.00      0.00     0.00        1     0.00     0.00  global constructors keyed to _Z3addii
  10. 0.00      0.00     0.00        1     0.00     0.00  __static_initialization_and_destruction_0(int, int)
  11. Call graph
  12. granularity: each sample hit covers 2 byte(s) no time propagated
  13. index % time    self  children    called     name
  14. 0.00    0.00       1/10001       main [7]
  15. 0.00    0.00   10000/10001       call() [10]
  16. [8]      0.0    0.00    0.00   10001         add(int, int) [8]
  17. -----------------------------------------------
  18. 0.00    0.00   10000/10000       call() [10]
  19. [9]      0.0    0.00    0.00   10000         sub(int, int) [9]
  20. -----------------------------------------------
  21. 0.00    0.00   10000/10000       main [7]
  22. [10]     0.0    0.00    0.00   10000         call() [10]
  23. 0.00    0.00   10000/10001       add(int, int) [8]
  24. 0.00    0.00   10000/10000       sub(int, int) [9]
  25. -----------------------------------------------
  26. 0.00    0.00       1/1           __do_global_ctors_aux [13]
  27. [11]     0.0    0.00    0.00       1         global constructors keyed to _Z3addii [11]
  28. 0.00    0.00       1/1           __static_initialization_and_destruction_0(int, int) [12]
  29. -----------------------------------------------
  30. 0.00    0.00       1/1           global constructors keyed to _Z3addii [11]
  31. [12]     0.0    0.00    0.00       1         __static_initialization_and_destruction_0(int, int) [12]
  32. -----------------------------------------------
  33. Index by function name
  34. [11] global constructors keyed to _Z3addii (hello_grof.cpp) [9] sub(int, int) [10] call()
  35. [8] add(int, int)          [12] __static_initialization_and_destruction_0(int, int) (hello_grof.cpp)

可以使用运行命令:

  1. gprof -b ./hello  gmon.out | gprof2doc.py > ~WWW/hello.dot

生成dot格式的调用关系图文件,可以使用windows版的GVEdit for Graphviz软件查看调用关系图:

附上一张比较复杂的程序调用关系图:

对于调用的关系和调用热点一目了然。

Gprof输出解读

这部分内容可将gprof -b ./hello中的-b参数去掉,可以显示字段的详细含义描述:

  1. 14  %         the percentage of the total running time of the
  2. 15 time       program used by this function.
  3. 16
  4. 17 cumulative a running sum of the number of seconds accounted
  5. 18  seconds   for by this function and those listed above it.
  6. 19
  7. 20  self      the number of seconds accounted for by this
  8. 21 seconds    function alone.  This is the major sort for this
  9. 22            listing.
  10. 23
  11. 24 calls      the number of times this function was invoked, if
  12. 25            this function is profiled, else blank.
  13. 26
  14. 27  self      the average number of milliseconds spent in this
  15. 28 ms/call    function per call, if this function is profiled,
  16. 29        else blank.
  17. 30
  18. 31  total     the average number of milliseconds spent in this
  19. 32 ms/call    function and its descendents per call, if this
  20. 33        function is profiled, else blank.
  21. 34
  22. 35 name       the name of the function.  This is the minor sort
  23. 36            for this listing. The index shows the location of
  24. 37        the function in the gprof listing. If the index is
  25. 38        in parenthesis it shows where it would appear in
  26. 39        the gprof listing if it were to be printed.

总结

gprof是常见的性能分析工具,在此罗列一下它的一些不足,也是从网上看的:

  • 1、对多线程支持不好,不准确
  • 2、必须退出exit()才行
  • 3、它只能分析应用程序在运行过程中所消耗掉的用户时间,无法得到程序内核空间的运行时间。对内核态的调用分析无能为力。如果程序系统调用比率比较大,就不适合。
时间: 2024-11-05 12:34:57

Linux C++程序进行性能分析工具gprof使用入门的相关文章

[转]程序进行性能分析工具gprof使用入门

性能分析工具 软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键.这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是要重点测试版本的性能表现和稳定性的.对于软件测试过程中发现的性能问题,如何定位有很多的方法.基本的方法可能是开发者对代码进行review,或者是使用一些工具对代码进行性能分析.常见的性能分析tuning工具有哪些呢?下面两篇文章做了详细的总结: https://computing.llnl.gov/

使用golang的pprof包对程序进行性能分析

程序经常出现OOM错误,然后关键字"go pprof"搜到文章<Go程序性能分析pprof>,该文章第二步说运行程序后会生成profile文件,但是编译运行后发现生成的profile文件大小一直为0,然后关键字"go pprof profile is empty"搜到文章<Golang pprof heap profile is empty>,该文章说在运行程序前添加环境变量GODEBUG="memprofilerate=1&quo

Linux系统程序包管理工具 RPM

什么是RPM: RPM全名是"RedHat Package Manager",简称为RPM,这套软件管理机制是由RedHat这家公司发展而来的.RPM是以一种数据库记录的方式来将你所需要的软件安装到你的Linux系统的一套管理机制.其最大的特点就是将你要安装的软件先编译过,并且打包成为RPM机制的安装包,通过包装好的软件里面默认的数据库记录这个软件安装时必须具备的依赖属性软件,具备就安装.不具备就不予安装. 程序的组成部分: 编译之前:源代码 编译文件 二进制程序:/bin, /sbi

Linux下程序包管理工具RPM

实验环境: CentOS release 6.6 (Final)  一台 IP地址:172.16.249.230 RPM 是 Red Hat Package Manager 的缩写,本意是Red Hat 软件包管理,顾名思义是Red Hat 贡献出来的软件包管理:在CentOS .Redhat.Fedora .SuSE.YellowDog等主流发行版本,以及在这些版本基础上二次开发出来的发行版采用: 一.RPM程序包管理的用途: 1.可以安装.删除.升级和管理软件:当然也支持在线安装和升级软件:

ubuntu上编译和使用easy_profiler对C++程序进行性能分析

本文首发于个人博客https://kezunlin.me/post/91b7cf13/,欢迎阅读最新内容! tutorial to compile and use esay profiler with c++ on ubuntu 16.04 Guide compile git clone https://github.com/yse/easy_profiler.git cd easy_profiler && mkdir build && cd build &&

高级工具gprof、gprof2dot.py、dot

可以研究程序性能.函数调用堆栈等,而且能用图标查看. linux环境下 C++性能测试工具 gprof + kprof + gprof2dot - 阁子 - 博客园 gprof.gprof2dot.py.dot使用方法简介 - Andy.Wang的博客 - 博客频道 - CSDN.NET 完.

C/C++性能分析工具gprof

转载自: linux环境下 C++性能测试工具 gprof + kprof + gprof2dot 添加-pg编译选项: gcc/g++ -g -pg file.c[c] 运行a.out 以 生成gmon.out ./a.out 生成中间分析文件 gprof ./a.out > prof.log 常用参数 -b brief的缩写 简要输出 gprof -b ./a.out > prof.log -q 打印函数调用关系 gprof -q ./a.out > prof.log -p prin

使用RPM包工具和源码包编译安装Linux应用程序

系统命令:一般在/bin和/sbin目录中,或为Shell内部指令,完成对系统的基本管理工作,例如IP配置工具 应用程序:通常在/usr/bin和/usr/sbin目录中,完成相对独立的其他辅助任务,例如网页浏览器 Linux应用程序的组成 /usr/bin     普通可执行程序文件,普通用户即可执行 /usr/sbin    服务器程序.管理程序文件,只有管理员能执行 /etc         配置文件,文件较多时会创建子目录 /var/log     日志文件 /usr/share/doc

Linux 系统性能分析工具sar一

sar(System Activity Reporter系统活动情况报告)是目前 Linux 上最为全面的系统性能分析工具之一,可以从多方面对系统的活动进行报告,包括:文件的读写情况.系统调用的使用情况.磁盘I/O.CPU效率.内存使用状况.进程活动及IPC有关的活动等.本文主要以CentOS 6.3 x64系统为例,介绍sar命令. sar命令常用格式 sar [options] [-A] [-o file] t [n] 其中: t为采样间隔,n为采样次数,默认值是1: -o file表示将命