77范文网 - 专业文章范例文档资料分享平台

嵌入式linux应用程序调试方法(8)

来源:网络收集 时间:2019-04-23 下载这篇文档 手机版
说明:文章内容仅供预览,部分内容可能不全,需要完整文档或者需要复制内容,请下载word后使用。下载word有问题请添加微信号:或QQ: 处理(尽可能给您提供完整文档),感谢您的支持与谅解。点击这里给我发消息

> The gprof program, for historical reasons, is sometimes excluded > from a cross-targeted toolchain. If you have a source tree with > a Cygnus configure script at the top level, or a gcc source tree, > then look for the \> configure.in, remove \ Then reconfigure the build tree, > and run \ That did it! Just to be clear, this is what I did: I untar'd the binutils-2.12.1 tar ball and edited binutils-2.12.1/configure.in. There's a line containing \ several packages (like gprof, sed,...); I removed gprof from that list. I then followed the instructions here for building binutils: http://sources.redhat.com/ecos/tools/linux-arm-elf.html and arm-elf-gprof was created! Score!

? 使用gprof

程序概要分析的概念非常简单:通过记录各个函数的调用和结束时间,我们可以计算出程序的最大运行时的程序段。这种方法听起来似乎要花费很多气力——幸运的是,我们其实离真理并不远!我们只需要在用 gcc 编译时加上一个额外的参数('-pg'),运行这个(编译好的)程序(来搜集程序概要分析的有关数据),然后运行“gprof”以更方便的分析这些结果。

案例分析: Pathalizer

我使用了一个现实中使用的程序来作为例子,是 pathalizer的一部分: 即event2dot,一个将路径“事件”描述文件转化为图形化“dot”文件的工具(executable which translates a pathalizer 'events' file to a graphviz 'dot' file)。

简单的说,它从一个文件里面读取各种事件,然后将它们分别保存为图像(以页为节点,且将页与页之间的转变作为边),然后将这些图像整合为一张大的图形,并保存为图形化的'dot'格式文件。

给程序计时

先让我们给我们未经优化的程序计一下时,看看它们的运行要多少时间。在我的计算机上使用event2dot并用源码里的例子作为输入(大概55000的数据),大致要三分多钟:

real 3m36.316s user 0m55.590s sys 0m1.070s

程序分析

要使用gprof 作概要分析,在编译的时候要加上'-pg' 选项,我们就是如下重新编译源码如下:

g++ -pg dotgen.cpp readfile.cpp main.cpp graph.cpp config.cpp -o event2dot

编译时编译器会自动在目标代码中插入用于性能测试的代码片断,这些代码在程序在运行时采集并记录函数的调用关系和调用次数,以及采集并记录函数自身执行时间和子函数的调用时间,程序运行结束后,会在程序退出的路径下生成一个gmon.out文件。这个文件就是记录并保存下来的监控数据。可以通过命令行方式的gprof或图形化的Kprof来解读这些数据并对程序的性能进行分析。另外,如果想查看库函数的profiling,需要在编译是再加入“-lc_p”编译参数代替“-lc”编译参数,这样程序会链接libc_p.a库,才可以产生库函数的profiling信息。如果想执行一行一行的profiling,还需要加入“-g”编译参数。

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

gprof 会显示出如下的函数比较重要:

% cumulative self self total time seconds seconds calls s/call s/call name

43.32 46.03 46.03 339952989 0.00 0.00 CompareNodes(Node *,Node *) 25.06 72.66 26.63 55000 0.00 0.00 getNode(char *,NodeListNode *&)

16.80 90.51 17.85 339433374 0.00 0.00 CompareEdges(Edge *,AnnotatedEdge *)

12.70 104.01 13.50 51987 0.00 0.00 addAnnotatedEdge(AnnotatedGraph *,Edge *) 1.98 106.11 2.10 51987 0.00 0.00 addEdge(Graph *,Node *,Node *) 0.07 106.18 0.07 1 0.07 0.07 FindTreshold(AnnotatedEdge *,int)

0.06 106.24 0.06 1 0.06 28.79 getGraphFromFile(char *,NodeListNode *&,Config *) 0.02 106.26 0.02 1 0.02 77.40 summarize(GraphListNode *,Config *) 0.00 106.26 0.00 55000 0.00 0.00 FixName(char *)

可以看出,第一个函数比较重要: 程序里面绝大部分的运行时都被它给占据了。 优化

上面结果可以看出,这个程序大部分的时间都花在了CompareNodes函数上,用 grep 查看一下则发现CompareNodes 只是被CompareEdges调用了一次而已, 而CompareEdges则只被addAnnotatedEdge调用——它们都出现在了上面的清单中。这儿就是我们应该做点优化的地方了吧!

我们注意到addAnnotatedEdge遍历了一个链表。虽然链表是易于实现,但是却实在不是最好的数据类

型。我们决定将链表 g->edges 用二叉树来代替: 这将会使得查找更快。

结果

现在我们看一下优化后的运行结果:

real 2m19.314s user 0m36.370s sys 0m0.940s

第二遍

再次运行 gprof 来分析:

% cumulative self self total time seconds seconds calls s/call s/call name

87.01 25.25 25.25 55000 0.00 0.00 getNode(char *,NodeListNode *&) 10.65 28.34 3.09 51987 0.00 0.00 addEdge(Graph *,Node *,Node *)

看起来以前占用大量运行时的函数现在已经不再是占用运行时的大头了!我们试一下再优化一下呢:用节点哈希表来取代节点树。

这次简直是个巨大的进步:

real 0m3.269s user 0m0.830s sys 0m0.090s

? gprof的输出信息

gprof的命令格式如下所示:

gprof OPTIONS EXECUTABLE-FILE gmon.out BB-DATA [YET-MORE-PROFILE-DATA-FILES...] [> OUTFILE]

gprof产生的信息含义如下所示: % time cumulative seconds self seconds the percentage of the total running time of the program used by this function. 函数使用时间占整个程序运行时间的百分比。 a running sum of the number of seconds accounted for by this function and those listed above it. 列表中包括该函数在内以上所有函数累计运行秒数。 the number of seconds accounted for by this function alone. This is the major sort for this listing. 函数本身所执行的秒数。

calls Self ms/call Total ms/call name the number of times this function was invoked, if this function is profiled, else blank. 函数被调用的次数 the average number of milliseconds spent in this function per call, if this function is profiled, else blank. 每一次调用花费在函数的时间microseconds。 the average number of milliseconds spent in this function and its descendents per call, if this function is profiled, else blank. 每一次调用,花费在函数及其衍生函数的平均时间microseconds。 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. 函数名

? 其他 C/C++ 程序分析器

还有其他很多分析器可以使用gprof 的数据, 例如KProf (截屏) 和 cgprof。虽然图形界面的看起来更舒服,但我个人认为命令行的gprof 使用更方便。

对其他语言的程序进行分析

我们这里介绍了用gprof 来对C/C++ 的程序进行分析,对其他语言其实一样可以做到: 对 Perl,我们可以用Devel::DProf 模块。你的程序应该以perl -d:DProf mycode.pl来开始,并使用dprofpp来查看并分析结果。如果你可以用gcj 来编译你的Java 程序,你也可以使用gprof,然而目前还只支持单线程的Java 代码。

? 结论

就像我们已经看到的,我们可以使用程序概要分析快速的找到一个程序里面值得优化的地方。在值得优化的地方优化,我们可以将一个程序的运行时从 3分36秒 减少到少于 5秒,就像从上面的例子看到的一样。

? References

Pathalizer: http://pathalizer.sf.net

KProf: http://kprof.sf.net

cgprof: http://mvertes.free.fr

Devel::DProf http://www.perldoc.com/perl5.8.0/lib/Devel/DProf.html

gcj: http://gcc.gnu.org/java

: pathalizer example files: download for article371 (http://www.fanqiang.com)

原文链接:http://main.linuxfocus.org/ChineseGB/March2005/article371.shtml

参考文献:

[1] 《掌握 Linux 调试技术》 Steve Best(sbest@us.ibm.com)JFS 核心小组成员,IBM 2002 年 8 月; 本文来源于IBM网站。

[2] nfs.sourceforge.net 网站上的HOWTO,和 FAQ文档; [3] 《building embedded linux systems》

[4] 《嵌入式linux系统开发详解--基于EP93XX系列ARM》 [5] 博客文章http://blog.sina.com.cn/u/1244756857

百度搜索“77cn”或“免费范文网”即可找到本站免费阅读全部范文。收藏本站方便下次阅读,免费范文网,提供经典小说综合文库嵌入式linux应用程序调试方法(8)在线全文阅读。

嵌入式linux应用程序调试方法(8).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印 下载失败或者文档不完整,请联系客服人员解决!
本文链接:https://www.77cn.com.cn/wenku/zonghe/622722.html(转载请注明文章来源)
Copyright © 2008-2022 免费范文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ: 邮箱:tiandhx2@hotmail.com
苏ICP备16052595号-18
× 注册会员免费下载(下载后可以自由复制和排版)
注册会员下载
全站内容免费自由复制
注册会员下载
全站内容免费自由复制
注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: