GNU Toolchain —— (六)gprof的应用
来源:互联网 发布:js跨域请求php 编辑:程序博客网 时间:2024/06/04 18:01
一 gprof功能简介
Gprof功能:打印出程序运行中各个函数消耗的时间,可以帮助程序员找出众多函数中耗时最多的函数。产生程序运行时候的函数调用关系,包括调用次数,可以帮助程序员分析程序的运行流程。
有了函数的调用关系,这会让开发人员大大提高工作效率,不用费心地去一点点找出程序的运行流 程,这对小程序来说可能效果不是很明显,但对于有几万,几十万代码量的工程来说,效率是毋庸置疑的!而且这个功能对于维护旧代码或者是分析Open Source来说那是相当诱人的,有了调用图,对程序的运行框架也就有了一个大体了解,知道了程序的"骨架",分析它也就不会再那么茫然,尤其是对自己不 熟悉的代码和Open Source。费话不多说了,让我们开始我们的分析之旅吧!
二 gprof实现原理
通过在编译和链接你的程序的时候(使用 -pg 编译和链接选项),gcc 在你应用程序的每个函数中都加入了一个名为mcount ( or"_mcount" , or "__mcount" , 依赖于编译器或操作系统)的函数,也就是说你的应用程序里的每一个函数都会调用mcount, 而mcount 会在内存中保存一张函数调用图,并通过函数调用堆栈的形式查找子函数和父函数的地址。这张调用图也保存了所有与函数相关的调用时间,调用次数等等的所有信息。
三 常用的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 显示使用次数为零的例程(按照调用计数和累积时间计算)。
四 尝试示例
Test.c
#include <stdio.h>
int prime(int n)
{
int i;
for (i=2; i<n; i++)
{
if (n%i == 0)
return 0;
return 1;
}
}
void main(void)
{
int i, n;
n = 1000;
for (i=2; i<=n; i++)
{
if (prime(i))
printf("%d/n", i);
}
}
Gcc -pg -o test test.c
./test
gprof -b test gmon.out |less
Flat profile:
Each sample counts as 0.01 seconds.
% cumulative self self total
time seconds seconds calls Ts/call Ts/call name
100.00 0.02 0.02 main
0.00 0.02 0.00 999 0.00 0.00 prime
^L
Call graph
granularity: each sample hit covers 4 byte(s) for50.00% of 0.02 seconds
index % time self children called name
<spontaneous>
[1] 100.0 0.02 0.00 main [1]
0.00 0.00 999/999 prime [2]
-----------------------------------------------
0.00 0.00 999/999 main [1]
[2] 0.0 0.00 0.00 999 prime [2]
-----------------------------------------------
^L
Index by function name
[1] main [2] prime
五 使用注意:
1) 一般gprof只能查看用户函数信息。如果想查看库函数的信息,需要在编译是再加入"-lc_p"编译参数代替"-lc"编译参数,这样程序会链接libc_p.a库,才可以产生库函数的profiling信息。
2) gprof只能在程序正常结束退出之后才能生成程序测评报告,原因是gprof通过在atexit()里注册了一个函数来产生结果信息,任何非正常退出都不会执行atexit()的动作,所以不会产生gmon.out文件。如果你的程序是一个不会退出的服务程序,那就只有修改代码来达到目的。如果不想改变程序的运行方式,可以添加一个信号处理函数解决问题(这样对代码修改最少),例如:
static void sighandler( intsig_no )
{
exit(0);
}
signal( SIGUSR1, sighandler );
当使用kill -USR1 pid 后,程序退出,生成gmon.out文件。
gprof产生的信息
% the percentage of the total running time of the
time program used by this function.
函数使用时间占所有时间的百分比。
cumulative a running sum of the number of secondsaccounted
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 isprofiled,
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.
函数名
扩展阅读:
· 1
http://hi.baidu.com/msingle/blog/item/672b76d7e77315daa144df0f.html
· 2
http://blog.sina.com.cn/s/blog_48da903c0100bpmx.html
· 3
http://hi.baidu.com/gulunmuer/blog/item/5fa473863fc4123b66096e22.html
转自 http://baike.baidu.com/view/2100555.htm
1.Graphviz 工具
看到这里你也可能觉得上面的函数调用图实在是不方便察看,也看不出来一个程序调用的整体框架。没有关系,我再介绍一个有用的工具给你,使用 Graphviz,Graphviz or Graph Visualization 是由 AT&T 开发的一个开源的图形可视化工具。它提供了多种画图能力,但是我们重点关注的是它使用 Dot 语言直连图的能力。在这里,将简单介绍如何使用 Dot 来创建一个图形,并展示如何将分析数据转换成 Graphviz 可以使用的规范, Dot 使用的图形规范。
使用 Dot 语言,你可以指定三种对象:图、节点和边。为了让你理解这些对象的含义,我将构建一个例子来展示这些元素的用法。
下图给出了一个简单的定向图(directed graph),其中包含 3 个节点。第一行声明这个图为 G,并且声明了该图的类型(digraph)。接下来的三行代码用于创建该图的节点,这些节点分别名为 node1、node2 和 node3。节点是在它们的名字出现在图规范中时创建的。边是在在两个节点使用边操作(->)连接在一起时创建的,如第 6 行到第 8 行所示。我还对边使用了一个可选的属性 label,用它来表示边在图中的名称。最后,在第 9 行完成对该图规范的定义。
使用 Dot 符号表示的示例图(test.dot)
Quote: 1: digraph G {
2: node1;
3: node2;
4: node3;
5:
6: node1 -> node2 [label="edge_1_2"];
7: node1 -> node3 [label="edge_1_3"];
8: node2 -> node3 [label="edge_2_3"];
9: }
要将这个 .dot 文件转换成一个图形映像,则需要使用 Dot 工具,这个工具是在 Graphviz 包中提供的。清单 6 介绍了这种转换。
清单 6. 使用 Dot 来创建 JPG 映像
[linux /home]$ dot -Tjpg test.dot -o test.jpg
在这段代码中,我告诉 Dot 使用 test.dot 图形规范,并生成一个 JPG 图像,将其保存在文件 test.jpg 中。所生成的图像如图1所示。在此处,我使用了 JPG 格式,但是 Dot 工具也可以支持其他格式,其中包括 GIF、PNG 和 post等等。
Dot 语言还可以支持其他一些选项,包括外形、颜色和很多属性。有兴趣可以查看graphviz相关文档。
2.从gprof的输出中提取调用图信息,产生可供Graphviz使用的dot文件。
这样的脚本有人已经实现了,我们只要下载一个现成的就可以了,首先从http://www.ioplex.com/~miallen/ 网站下载一个mkgraph脚本。解压该脚本到包含gmon.out文件的目录下。使用mkgraph0.sh产生调用的jpg图像文件。例如:使用上面的例子,生成cflow的调用图。
[linux /home/cflow-1.1/src]$ mkgraph0.sh cflow gmon.out
部分调用图如下,有了这个图是不是对程序整体框架有了个清晰地了解,如果你对生成的调用图效果不满意,你还可以通过修改mkgraph0脚本使之产生合适的dot文件即可:
转自 http://www.360doc.com/content/10/0429/11/474846_25401101.shtml
- GNU Toolchain —— (六)gprof的应用
- GNU toolchain —— (一)介绍
- GNU Toolchain —— (三)gdb 调试
- GNU Toolchain —— (二)GCC参数详解
- GNU Toolchain —— (五)gcov与lcov入门
- GNU Toolchain —— (三)gdb 调试续
- gprof——GNU性能分析工具
- gprof——GNU性能分析工具
- gprof——GNU性能分析工具
- gprof——GNU性能分析工具
- gprof——GNU性能分析工具
- gprof——GNU性能分析工具
- gprof——GNU性能分析工具
- GNU工具链(GNU toolchain)
- GNU Toolchain —— (四)例解 autoconf 和 automake 生成 Makefile 文件
- GNU toolchain
- GNU gprof
- GNU gprof
- E63安装主题,报证书错误,该怎么解决??
- 关于c#WINFORM的开发文摘
- linux串口编程
- 测试自动化 2011-01-04 GTest
- Start with linux in Debian 5
- GNU Toolchain —— (六)gprof的应用
- 有趣的问题(一)
- 简单的go以及begin和end使用
- U-Boot启动过程完全分析
- 复制数据至剪贴板
- fedora MySql Cluster 搭建
- Silverlight:三个基本布局控件(Canvas、StackPanel、Grid )
- 网页常用Javascript
- killprocess