参考

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. 单链表之删除头结点,查找等于定值x的结点数,单链表的逆置

    /* * @Author: 一届书生 * @Date: 2020-03-08 09:52:27 * @LastEditTime: 2020-03-08 13:58:30 */ #include < ...

  2. 我用这10招,能减少了80%的BUG

    前言 对于大部分程序员来说,主要的工作时间是在开发和修复BUG. 有可能修改了一个BUG,会导致几个新BUG的产生,不断循环. 那么,有没有办法能够减少BUG,保证代码质量,提升工作效率? 答案是肯定 ...

  3. dbeaver导出结果集中乱码

    重要的一步 需要点击

  4. 力扣400(java)-第N位数字(中等)

    题目: 给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n 位上的数字. 示例 1: 输入:n = 3输出: ...

  5. 团队管理|如何提高技术Leader的思考技巧?

    简介: 技术Leader是一个对综合素质要求非常高的岗位,不仅要有解具体技术问题的架构能力,还要具备团队管理的能力,更需要引领方向带领团队/平台穿越迷茫进阶到下一个境界的能力.所以通常来说技术Lead ...

  6. 阿里云 EMR Delta Lake 在流利说数据接入中的架构和实践

    简介: 为了消灭数据孤岛,企业往往会把各个组织的数据都接入到数据湖以提供统一的查询或分析.本文将介绍流利说当前数据接入的整个过程,期间遇到的挑战,以及delta在数据接入中产生的价值. 背景 流利说目 ...

  7. 阿里云CDN产品经理陈章炜:边缘创新技术和落地实践

    简介: CDN除了加速外,不断被赋予更多价值.在阿里云CDN推出的<极速奔跑吧 2021>首场直播中,阿里云架构师和产品经理不仅对近期阿里云发布的CDN产品最佳实践图进行了详细解读,还对C ...

  8. 为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?

    简介: 江娱互动是一家新兴的游戏企业,自 2018 年成立伊始,江娱互动就面向广阔的全球游戏市场,通过创造有趣的游戏体验,在竞争激烈的游戏市场占得一席之地.仅仅 2 年的时间,江娱互动就凭借 Topw ...

  9. 5.prometheus监控--监控nginx

    1.监控程序环境准备 mkdir /data/docker-compose -p cd /data/docker-compose cat > docker-compose.yaml <&l ...

  10. PostMan接口测试实用小点

    PostMan接口测试实用小点 1. 接口测试变量存取操作 在Postman中有很多地方可以存储一些变量,这里只介绍经常使用的环境变量.变量设置后,在UI界面可以通过{{变量名}}获取到对应值. 在环 ...