参考

gprof的简单使用-anthony1983-ChinaUnix博客

Top (GNU gprof) (sourceware.org)

c - Enable and disable gprof at runtime? - Stack Overflow

gprof——GNU性能分析工具 - feisky - 博客园 (cnblogs.com)

Linux性能优化gprof使用 - youxin - 博客园 (cnblogs.com)

gprof介绍

GNU分析工具gprof可以有用的测量程序的性能,它记录了调用每个函数的次数以及在每个函数上花费的时间。

从gprof的输出可以容易的看出占用大量运行时间的函数。提高程序运行速度应该首先集中在那些占据费时的函数上。

使用方式

gprof [可执行文件] [gmon.out文件] [其它参数]

方括号中的内容可以省略。如果省略了“可执行文件”,gprof会在当前目录下搜索a.out文件作为可执行文件;

如果省略了gmon.out文件,gprof也会在当前目录下寻找gmon.out。

其它参数可以控制gprof输出内容的格式等信息,最常用的参数如下:

  • -b:不再输出统计图表中每个字段的详细描述。

  • -p:只输出函数的调用图(Call graph的那部分信息)。

  • -q:只输出函数的时间消耗列表。

  • -e Name:不再输出函数Name 及其子函数的调用图(除非它们有未被限制的其它父函数)。可以给定多个 -e 标志。一个 -e 标志只能指定一个函数。

  • -E Name:不再输出函数Name 及其子函数的调用图,此标志类似于 -e 标志,但它在总时间和百分比时间的计算中排除了由函数Name 及其子函数所用的时间。

  • -f Name:输出函数Name 及其子函数的调用图。可以指定多个 -f 标志。一个 -f 标志只能指定一个函数。

  • -F Name:输出函数Name 及其子函数的调用图,它类似于 -f 标志,但它在总时间和百分比时间计算中仅使用所打印的例程的时间。可以指定多个 -F 标志。一个 -F 标志只能指定一个函数。-F 标志覆盖 -E 标志。

  • -z:显示使用次数为零的例程(按照调用计数和累积时间计算)。

使用步骤

  1. 使用gcc/g++编译时,加参数-pg,比如gcc -pg -o test test.c
  2. 运行编译好的程序test,程序会产生gmon.out文件
  3. 使用gprof工具分析gmon.out文件,gprof ./test gmon.out。

测试代码:

#include <stdio.h>

/* Computes the length of Collatz sequences */
unsigned int step(unsigned int x)
{
if (x % 2 == 0) {
return (x / 2);
} else {
return (3 * x + 1);
}
} unsigned int nseq(unsigned int x0)
{
unsigned int i = 1, x;
if (x0 == 1 || x0 == 0)
return i;
x = step(x0);
while (x != 1 && x != 0) {
x = step(x);
i++;
}
return i;
} int main(void)
{
unsigned int i, m = 0, im = 0;
for (i = 1; i < 500000; i++) {
unsigned int k = nseq(i);
if (k > m) {
m = k;
im = i;
printf("sequence length = %u for %u\n", m, im);
}
}
return 0;
}

编译、运行、测试:

$ gcc -pg -o gprof_test gprof_test.c
$ ./gprof_test
$ gprof ./gprof_test gmon.out -b
Flat profile: Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ns/call ns/call name
75.82 0.30 0.30 62135400 4.88 4.88 step
20.22 0.38 0.08 499999 161.76 768.35 nseq
2.53 0.39 0.01 frame_dummy
2.53 0.40 0.01 main Call graph granularity: each sample hit covers 2 byte(s) for 2.47% of 0.40 seconds index % time self children called name
<spontaneous>
[1] 97.5 0.01 0.38 main [1]
0.08 0.30 499999/499999 nseq [2]
-----------------------------------------------
0.08 0.30 499999/499999 main [1]
[2] 95.0 0.08 0.30 499999 nseq [2]
0.30 0.00 62135400/62135400 step [3]
-----------------------------------------------
0.30 0.00 62135400/62135400 nseq [2]
[3] 75.0 0.30 0.00 62135400 step [3]
-----------------------------------------------
<spontaneous>
[4] 2.5 0.01 0.00 frame_dummy [4]
----------------------------------------------- Index by function name [4] frame_dummy [2] nseq
[1] main [3] step

测试结果

  • % time:当前函数占总的运行时间的百分比
  • cumulative seconds:函数和上列函数累计执行的时间,单位秒
  • self seconds:函数本身执行的时间
  • calls:函数被调用次数
  • self ms/call:每一次调用花费在函数的时间
  • total ms/call:每一次调用,花费在函数及其依赖函数的平均时间
  • name:函数名
$ gprof ./gprof_test gmon.out -b
Flat profile: Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls ns/call ns/call name
75.82 0.30 0.30 62135400 4.88 4.88 step
20.22 0.38 0.08 499999 161.76 768.35 nseq
2.53 0.39 0.01 frame_dummy
2.53 0.40 0.01 main

Call graph 信息解释:

  • index:索引值
  • % time:函数消耗时间占所有时间百分比
  • Self:函数本身执行时间
  • Children:执行子函数所用时间
  • Called:被调用次数
  • Name:函数名
index % time    self  children    called     name
<spontaneous>
[1] 97.5 0.01 0.38 main [1]
0.08 0.30 499999/499999 nseq [2]
-----------------------------------------------
0.08 0.30 499999/499999 main [1]
[2] 95.0 0.08 0.30 499999 nseq [2]
0.30 0.00 62135400/62135400 step [3]
-----------------------------------------------
0.30 0.00 62135400/62135400 nseq [2]
[3] 75.0 0.30 0.00 62135400 step [3]
-----------------------------------------------
<spontaneous>
[4] 2.5 0.01 0.00 frame_dummy [4]
----------------------------------------------- Index by function name [4] frame_dummy [2] nseq
[1] main [3] step

缺点

  • 只能分析应用程序在运行过程中所消耗掉的用户时间,无法得到程序内核空间的运行时间。

    查看内核空间运行时间的方式,可以使用time命令:

    $ time ./test
    real 0m0.591s 实际运行时间
    user 0m0.498s 用户态运行时间
    sys 0m0.093s 内核态运行时间
  • 分析的执行时间不包括由于挂起和阻塞的时间,所以对于有大量阻塞调用和休眠挂起的程序,使用gprof进行分析,并不能很好的分析出程序瓶颈的所在。gprof以固定的周期对程序运行时间进行采样测量,当程序挂起时,gprof不会对程序进行采样测量。

    解决方式:如果只对某部分代码进行分析,可以在不需要进行分析的代码段调用moncontrol(0)关闭分析,然后在需要分析的代码段调用moncontrol(1)打开分析。

    extern void moncontrol(int);
    moncontrol(0);
    moncontrol(1);
  • 不支持动态库中的函数分析

GNU gprof分析C性能的更多相关文章

  1. C/C++性能测试工具GNU gprof

    代码剖析(Code profiling)程序员在优化软件性能时要注意应尽量优化软件中被频繁调用的部分,这样才能对程序进行有效优化.使用真实的数据,精确的分析应用程序在时间上的花费的行为就成为_代码剖析 ...

  2. GNU Linux高并发性能优化方案

    /*********************************************************** * Author : Samson * Date : 07/14/2015 * ...

  3. 使用show profiles分析SQL性能

    如何查看执行SQL的耗时 使用show profiles分析sql性能. Show profiles是5.0.37之后添加的,要想使用此功能,要确保版本在5.0.37之后. 查看数据库版本 mysql ...

  4. google perftools分析程序性能

    Google perftools 1.功能简介 它的主要功能就是通过采样的方式,给程序中cpu的使用情况进行“画像”,通过它所输出的结果,我们可以对程序中各个函数(得到函数之间的调用关系)耗时情况一目 ...

  5. 【MS SQL】通过执行计划来分析SQL性能

    原文:[MS SQL]通过执行计划来分析SQL性能 如何知道一句SQL语句的执行效率呢,只知道下面3种: 1.通过SQL语句执行时磁盘的活动量(IO)信息来分析:SET STATISTICS IO O ...

  6. 用 CPI 火焰图分析 Linux 性能问题

    https://yq.aliyun.com/articles/465499 用 CPI 火焰图分析 Linux 性能问题   yangoliver 2018-02-11 16:05:53 浏览1076 ...

  7. 【PHP】善用php-fpm的慢执行日志slow log,分析php性能问题

    (转)善用php-fpm的慢执行日志slow log,分析php性能问题  众所周知,mysql有slow query log,根据慢查询日志,我们可以知道那些sql语句有性能问题.作为mysql的好 ...

  8. 大数据学习--day14(String--StringBuffer--StringBuilder 源码分析、性能比较)

    String--StringBuffer--StringBuilder 源码分析.性能比较 站在优秀博客的肩上看问题:https://www.cnblogs.com/dolphin0520/p/377 ...

  9. Nginx 日志分析及性能排查

    Nginx 日志分析及性能排查 2017-03-04 Linux爱好者 (点击上方公众号,可快速关注) 作者:-外星人- my.oschina.net/362228416/blog/844713 如有 ...

  10. mysql show profiles使用分析sql性能

    mysql show profiles使用分析sql性能 Show profiles是5.0.37之后添加的,要想使用此功能,要确保版本在5.0.37之后. 查看一下我的数据库版本 mysql> ...

随机推荐

  1. 周博磊老师强化学习纲领笔记第二课:MDP,Policy Iteration与Value Iteration

    gym环境:FrozenLake-v0:http://gym.openai.com/envs/FrozenLake-v0/ 代码来自:周博磊老师的GitHub:https://github.com/c ...

  2. 剑指 Offer II 018(Java). 有效的回文(简单)

    题目: 给定一个字符串 s ,验证 s 是否是 回文串 ,只考虑字母和数字字符,可以忽略字母的大小写. 本题中,将空字符串定义为有效的 回文串 . 示例 1: 输入: s = "A man, ...

  3. 力扣554(java&python)-砖墙(中等)

    题目: 你的面前有一堵矩形的.由 n 行砖块组成的砖墙.这些砖块高度相同(也就是一个单位高)但是宽度不同.每一行砖块的宽度之和相等. 你现在要画一条 自顶向下 的.穿过 最少 砖块的垂线.如果你画的线 ...

  4. 实时化或成必然趋势?新一代 Serverless 实时计算引擎

    作者:高旸(吾与),阿里巴巴高级产品专家 本文由阿里巴巴高级产品专家高旸(吾与)分享,主要介绍新一代Serverless实时计算引擎的产品特性及核心功能. 一.实时计算 Flink 版 – 产品定位与 ...

  5. 贾扬清演讲实录:一个AI开发者的奇幻漂流

    ​简介:2021阿里灵杰AI工程化峰会,贾扬清深度解读阿里灵杰大数据和AI一体化平台. 演讲人:贾扬清 演讲主题:一个AI开发者的奇幻漂流 活动:2021阿里灵杰AI工程化峰会 对于绝大多数人来说,这 ...

  6. WPF 已知问题 资源字典树引用与资源寻找的坑

    大家都知道,在 WPF 里面,可以让资源字典合并其他资源字典,从而定义出资源字典引用树.然而在资源字典引用树里面,如果没有理清关系,将可以作出一个超级复杂的引用关系网.如果在性能优化中,将网断开部分, ...

  7. 8.prometheus监控--监控Mysql8.0

    一.环境搭建 docker-compose安装mysql mkdir /data/mysql -p cd /data/mysql cat > docker-compose.yaml <&l ...

  8. 羽夏壳世界—— PE 解析的实现

    写在前面   此系列是本人一个字一个字码出来的,包括代码实现和效果截图. 如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你的,如有闲钱,可以打赏支持我的创作.如想转载,请把我的转载信息附在文章后 ...

  9. vue3早已具备抛弃虚拟DOM的能力了

    前言 jquery时代更新视图是直接对DOM进行操作,缺点是频繁操作真实 DOM,性能差.react和vue时代引入了虚拟DOM,更新视图是对新旧虚拟DOM树进行一层层的遍历比较,然后找出需要更新的D ...

  10. WPF 纯xaml实现控件运动动画

    1.Image控件加载后上下运动 2.Image控件可以放在Grid等布局控件中 3.指定加载时触发动画: EventTrigger RoutedEvent="Image.Loaded&qu ...