一、gprof介绍

gprof是GNU

profiler工具。可以显示程序运行的“flat profile”,包括每个函数的调用次数,每个函数消耗的处理器时间。也可以显示“调用图”,包括函数的调用关系,每个函数调用花费了多少时间。还可以显示“注释的源代码”,是程序源代码的一个复本,标记有程序中每行代码的执行次数。

二、Gprof功能:

打印出程序运行中各个函数消耗的时间,可以帮助程序员找出众多函数中耗时最多的函数。

产生程序运行时候的函数调用关系,包括调用次数,可以帮助程序员分析程序的运行流程。有了函数的调用关系,这会让开发人员大大提高工作效率,不用费心地去一点点找出程序的运行流程,这对小程序来说可能效果不是很明显,但对于有几万,几十万代码量的工程来说,效率是毋庸置疑的!而且这个功能对于维护旧代码或者是分析Open

Source来说那是相当诱人的,有了调用图,对程序的运行框架也就有了一个大体了解,知道了程序的“骨架“,分析它也就不会再那么茫然,尤其是对自己不熟悉的代码和Open

Source。费话不多说了,让我们开始我们的分析之旅吧!

三、Gprof实现原理:

通过在编译和链接你的程序的时候(使用

-pg编译和链接选项),gcc在你应用程序的每个函数中都加入了一个名为mcount

( or “_mcount” ,

or “__mcount” ,

依赖于编译器或操作系统)的函数,也就是说你的应用程序里的每一个函数都会调用mcount, 而mcount

会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间,调用次数等等的所有信息。

程序运行结束后,会在程序退出的路径下生成一个gmon.out文件。这个文件就是记录并保存下来的监控数据。可以通过命令行方式的gprof或图形化的Kprof来解读这些数据并对程序的性能进行分析。

另外,如果想查看库函数的profiling,需要在编译是再加入“-lc_p”编译参数代替“-lc”编译参数,这样程序会链接libc_p.a库,才可以产生库函数的profiling信息。如果想执行一行一行的profiling,还需要加入“-g”编译参数。

四、gprof的适用范围

gprof可以用来分析系统在运行时各函数调用的次数,耗时等情况,可以方便地帮助我们定位系统的瓶颈,同时也能让我们知道对程序的那个位置就行优化能够带来尽可能大的性能提升。gprof优化尤其适用于CPU、内存密集性的应用模块。

五、gprof的安装使用

目前我们的linux主机上大多都安装了gprof,详细的参数等可以通过man

gprof查看。需要重点指出的是,目前我们线上的gprof对多线程的支持不好,直接调用只能得到主线程的相关调用情况。根据相关资料,原因为gprof采用ITIMER_PROF信号,在多线程内,只有主线程才能响应该信号。为此,需要做一些额外的工作。使用提供的gprof-helper.c,将其编译为so库,命令为:gcc

-shared -fPICgprof-helper.c -o gprof-helper.so -lpthread

-ldl

这个库的作用实际上实现一个pthread_create的钩子程序,这样我们在调用pthread_create函数的时候就会调用到这个库中提供的pthread_create的函数,从而实现在多线程情况下统计运行时的相关信息。

在实际使用中,方法比较简单,在我们自己的程序的makefile文件中,加上编译的选项-pg,并加上那个动态链接库。如gcc

-pg imbs_main.cpp ../gprof-helper.so$(INCLUDE) $(LDFLAGS)

$(LDLIBS)。

这样在编译后会生成一个a.out文件。这个文件就是包含了相关统计功能的可执行文件,和我们正常编译的程序在对外行为上是完全一致的。

程序运行并“正常”退出后,会生成一个gmon.out文件,这个就是运行时的统计文件。使用命令gprof

-ba.out gmon.out就可以将最终我们readable的信息输出来。这些信息可以作为我们优化的依据。

注意:上面提到的“正常”退出是指程序是按照自身的运行逻辑正常退出的,如果直接killall

-9是不能得到统计结果的。而我们通常的程序都是在循环中长时间运行,所以,实际中采用了相应SIGTERM信号的方式,使用killall-s

15,发送SIGTERM信号给程序,程序中会有相应的函数捕捉该信号,捕捉到该信号后,置一个退出标记,这样我们就可以控制程序按照既定的逻辑在处理完一次完整的工作后正常的退出。

这又引出了另一个问题,实际上我们现在上线程序,重启程序的时候,通常都是使用killall

-9来停止原有程序的。这实际上是存在较大风险的,举例来说,如果程序在执行时存在一些持久化的操作,比如写磁盘,同时,写磁盘操作是多次完成,比如先写数据、再写索引等,这应该是一个在逻辑上的原子操作,那么killall

-9的随机性可能破坏其原子性,从而造成潜在的数据不一致,如在我们常用的transfer中就存在这种数据不一致的隐患。虽然出现的概率不是很高,但是,长期的积累这种不一致性是会慢慢体现出来的。

六、Gprof基本用法:

1.使用-pg选项编译和链接你的应用程序。2.执行你的应用程序,使之运行完成后生成供gprof分析的数据文件(默认是gmon.out)。3.使用gprof程序分析你的应用程序生成的数据,例如:gprof a.out gmon.out。

举例

gcc-Wall -pg -o

testtest.c //程序文件名称test.c编译时使用–pg

现在我们可以再次运行test,并使用我们前面使用的测试数据。这次我们运行的时候,test运行的分析数据会被搜集并保存在'gmon.out'文件中,我们可以通过运行'

gprof test '来查看结果。

./test

gproftest

七、gprof产生的信息

% the

percentage of the total running time of the

time program

used by this function.函数使用时间占所有时间的百分比。cumulative a running sumof the number of seconds accounted

seconds for

by this function and those listed above it.函数和上列函数累计执行的时间。self the

number of seconds accounted for by this

seconds function

alone. This is the major sort for this

listing.函数本身所执行的时间。calls the

number of times this function was invoked, if

this

function is profiled, else blank.函数被调用的次数self the

average number of milliseconds spent in this

ms/call function

per call, if this function is profiled,

else

blank.每一次调用花费在函数的时间microseconds。total the

average number of milliseconds spent in this

ms/call function

and its descendents per call, if this

function

is profiled, else blank.每一次调用,花费在函数及其衍生函数的平均时间microseconds。name the

name of the function. This is the minor sort

for

this listing. The index shows the location of

the

function in the gprof listing. If the index is

in

parenthesis it shows where it would appear in

the

gprof listing if it were to be printed.函数名

九、Gprof简单使用:

让我们简单的举个例子来看看Gprof是如何使用的。

9.1.打开linux终端。

新建一个test.c文件,并生用-pg

编译和链接该文件。 test.c 文件内容如下:

#include

#include

void

a()

{

printf("\t\t+---call a() function\n");

}

void

c()

{

printf("\t\t+---call c() function\n");

}

int

b()

{

printf("\t+---

call

b() function\n");

a();

c();

return

0;

}

int

main()

{

printf(" main() function()\n");

b();

return 0;

}

命令行里面输入下面命令,没加-c选项,gcc

会默认进行编译并链接生成a.out:

[linux

/home/test]$gcc

-pg test.c

入果没有编译错误,gcc会在当前目录下生成一个a.out文件,当然你也可以使用

–o 选项给生成的文件起一个别的名字,像 gcc –pg test.c –o test,

则gcc会生成一个名为test的可执行文件,在命令行下输入[linux/home/test]$./test ,

就可以执行该程序了,记住一定要加上 ./ 否则程序看上去可能是执行,可是什么输出都没有。

9.2.执行你的应用程序使之生成供gprof分析的数据。命令行里面输入:

[linux

/home/test]$a.out

main()

function()

+--- call b()

function

+---call a()

function

+---call c()

function

[linux

/home/test]$

你会在当前目录下看到一个gmon.out文件,

这个文件就是供gprof 分析使用的。

9.3.使用gprof程序分析你的应用程序生成的数据。

令行里面输入:

[linux

/home/test]$ gprof

-b a.out gmon.out

| less

% cumulative self self total

time seconds seconds calls Ts/call Ts/call name

0.00 0.00 0.00 1 0.00 0.00 a

0.00 0.00 0.00 1 0.00 0.00 b

0.00 0.00 0.00 1 0.00 0.00 c

Call graph

granularity: each sample hit covers

4 byte(s) no time propagated

index

% time self children called name

0.00 0.00 1/1 b [2]

[1] 0.0 0.00 0.00 1 a [1]

-----------------------------------------------

0.00 0.00 1/1 main [10]

[2] 0.0 0.00 0.00 1 b [2]

0.00 0.00 1/1 a [1]

0.00 0.00 1/1 c [3]

-----------------------------------------------

0.00 0.00 1/1 b [2]

[3]

Linux下终端的相关函数,gprof 使用和介绍相关推荐

  1. linux 控制台输入命令无效_解决linux下终端无法输入的假死问题

    有时在linux下shell终端中,会突然出现终端应用卡死,无法接受键盘输入, 但是其它分屏, 系统都是正常的.这本来是一个终端的很老的功能, 叫软件流控制(XON/XOFF flow control ...

  2. 解决linux下终端无法输入的假死问题

    有时在linux下shell终端中,会突然出现终端应用卡死,无法接受键盘输入, 但是其它分屏, 系统都是正常的.这本来是一个终端的很老的功能, 叫软件流控制(XON/XOFF flow control ...

  3. Linux下时间处理相关函数

    Linux下时间处理相关函数 1 .系统时间和 RTC 时间   Linux 系统下包含两个时间: 系统时间和 RTC 时间.   系统时间: 是由主芯片的定时器进行维护的时间, 一般情况下都会选择芯 ...

  4. [转]Linux下pppoe配合Drcom插件上网方法介绍......

    Linux下pppoe配合Drcom插件上网方法介绍 近几天在西邮bbs上闲逛,无意间注意到很多人纠结于同一个问题---linux上网,众所周知,linux系统在宿舍上网时比较烦人的一件事,虽然bbs ...

  5. linux内核vrrp配置,在Linux下的(VRRP)虚拟路由冗余协议介绍(转)

    在Linux下的(VRRP)虚拟路由冗余协议介绍(转)[@more@] 这篇文章描述的是如何在Linux下实现VRRP (Virtual Router Redundancy Protocol 虚拟路由 ...

  6. linux下终端urvst,Linux中的静态库与动态库

    #什么是库文件? 库文件是事先编译好的方法的合集.比如:我们提前写好一些数据公式的实现,将其打包成库文件,以后使用只需要库文件就可以,不需要重新编写. #Linux系统中: 1.静态库的扩展名为.a: ...

  7. 解决Linux下终端无法输入的假死现象

    参照:https://www.cnblogs.com/guochaoxxl/p/10428991.html 有时在linux下shell终端中,会突然出现终端应用卡死,无法接受键盘输入, 但是其它分屏 ...

  8. Linux下终端上传文件到Openwrt路由器中

    windows下可以用winscp.exe连接路由器,但是Linux下不可行 折腾了好久,总算发现linux下可以用scp来上传文件到路由器里面去 指定要上传的文件myfile.tar.gz,路由器用 ...

  9. linux下终端命令快捷键

    (转载) 终端快捷键 tab=补全  ctrl+a=开始位置  ctrl+e=最后位置  alt+shift+f 光标位置移动到前一个单词  alt+shift+b 光标位置移动到后一个单词  ctr ...

最新文章

  1. numpy和torch数据操作对比
  2. VCSA 6.5 HA 配置之五:故障转移测试
  3. 浅谈人工智能应对数字化转型挑战的5个领域
  4. Quartz使用示例总结
  5. 光流法 Optical Flow
  6. 计算机科学与技术 单片机,单片机-兰州交通大学计算机科学与技术实验教学中心...
  7. Mysql学习笔记(七)查(补充)
  8. 火狐ok谷歌适配_“ OK Google”在锁定手机上的安全性越来越高
  9. wxpython窗口跳转_WxPython-用按钮打开一个新窗口
  10. 网络安全模型_工业互联网态势感知,看得见的网络安全
  11. 机器学习--详解贝叶斯公式、朴素贝叶斯的来龙去脉(附上多方式代码实现)
  12. 转载 分布式协调技术 分布式锁
  13. 【转】Swig 使用指南
  14. mysql 事物gljbie,提升mysql性能几大参数丶章怀柔
  15. VARCHART XGantt 甘特图如何创建和修改数据记录
  16. 【Opencv】 于仕琪 人脸68个特征点分布情况
  17. 一台计算机可以安装网络打印机和本地打印机,您在计算机上安装一台本地打印机。您共享这台打印机。您需要确保只有名为Grou - 问答库...
  18. 8根网线的排序和作用
  19. 【经验贴】本科生毕业论文答辩经验
  20. 人体反应测试仪 c语言,FD.12-FD-HRT-A

热门文章

  1. 边缘AI新方法TinyML,超低功耗,存储占用KB计,在边缘设备上进行机器学习
  2. 良心安利底纹免抠元素素材网站
  3. java做钟表时间_求助,关于时间钟表设置时间的问题
  4. docker启动容器服务之后访问失败
  5. 使用MFC界面库LibUIDK
  6. ARMv7-A 处理器窥探(1) —— 处理器模式
  7. tower(普及组多校模拟赛)
  8. 15.4 CVPR 2015 papers
  9. 3GPP R17标准延期
  10. SQL练习题 (学生信息表 教师信息 课程信息等)