国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > C++ > 正文

使用GProf來優(yōu)化你的C/C++程序

2020-05-23 14:24:23
字體:
供稿:網(wǎng)友

GProf 使用了一種異常簡單但是非常有效的方法來優(yōu)化C/C++ 程序,而且能很容易的識別出值得優(yōu)化的代碼。一個簡單的案例分析將會顯示,GProf如何通過識別并優(yōu)化兩個關(guān)鍵的數(shù)據(jù)結(jié)構(gòu),將實際應(yīng)用中的程序從3分鐘的運行時優(yōu)化到5秒的。

  這個程序最早可以追溯到1982年關(guān)于編譯器構(gòu)建的特別討論大會(the SIGPLAN Symposium on Compiler Construction)?,F(xiàn)在這個程序成了各種UNIX 平臺上的一個標準工具。

  _________________ _________________ _________________

  Profiling in a nutshell

  程序概要分析的概念非常簡單:通過記錄各個函數(shù)的調(diào)用和結(jié)束時間,我們可以計算出程序的最大運行時的程序段。這種方法聽起來似乎要花費很多氣力——幸運的是,我們其實離真理并不遠!我們只需要在用 gcc 編譯時加上一個額外的參數(shù)('-pg'),運行這個(編譯好的)程序(來搜集程序概要分析的有關(guān)數(shù)據(jù)),然后運行'gprof'以更方便的分析這些結(jié)果。

  案例分析: Pathalizer

  我使用了一個現(xiàn)實中使用的程序來作為例子,是 pathalizer的一部分: 即event2dot,一個將路徑“事件”描述文件轉(zhuǎn)化為圖形化“dot”文件的工具(executable which translates a pathalizer 'events' file to a graphviz 'dot' file)。

  簡單的說,它從一個文件里面讀取各種事件,然后將它們分別保存為圖像(以頁為節(jié)點,且將頁與頁之間的轉(zhuǎn)變作為邊),然后將這些圖像整合為一張大的圖形,并保存為圖形化的'dot'格式文件。

  給程序計時

  先讓我們給我們未經(jīng)優(yōu)化的程序計一下時,看看它們的運行要多少時間。在我的計算機上使用event2dot并用源碼里的例子作為輸入(大概55000的數(shù)據(jù)),大致要三分多鐘:

  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

  現(xiàn)在我們可以再次運行event2dot,并使用我們前面使用的測試數(shù)據(jù)。這次我們運行的時候,event2dot運行的分析數(shù)據(jù)會被搜集并保存在'gmon.out'文件中,我們可以通過運行'gprof event2dot | less'來查看結(jié)果。

  gprof 會顯示出如下的函數(shù)比較重要:

  % 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 *)

  可以看出,第一個函數(shù)比較重要: 程序里面絕大部分的運行時都被它給占據(jù)了。

  優(yōu)化

  上面結(jié)果可以看出,這個程序大部分的時間都花在了CompareNodes函數(shù)上,用 grep 查看一下則發(fā)現(xiàn)CompareNodes 只是被CompareEdges調(diào)用了一次而已, 而CompareEdges則只被addAnnotatedEdge調(diào)用——它們都出現(xiàn)在了上面的清單中。這兒就是我們應(yīng)該做點優(yōu)化的地方了吧!

  我們注意到addAnnotatedEdge遍歷了一個鏈表。雖然鏈表是易于實現(xiàn),但是卻實在不是最好的數(shù)據(jù)類型。我們決定將鏈表 g->edges 用二叉樹來代替: 這將會使得查找更快。

  結(jié)果

  現(xiàn)在我們看一下優(yōu)化后的運行結(jié)果:

  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 *)

  看起來以前占用大量運行時的函數(shù)現(xiàn)在已經(jīng)不再是占用運行時的大頭了!我們試一下再優(yōu)化一下呢:用節(jié)點哈希表來取代節(jié)點樹。

  這次簡直是個巨大的進步:

  real 0m3.269s

  user 0m0.830s

  sys 0m0.090s

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

  還有其他很多分析器可以使用gprof 的數(shù)據(jù), 例如

  

  

使用GProf來優(yōu)化你的C/C++程序

  

  KProf (截屏) 和 cgprof。雖然圖形界面的看起來更舒服,但我個人認為命令行的gprof 使用更方便。

  對其他語言的程序進行分析

  我們這里介紹了用gprof 來對C/C++ 的程序進行分析,對其他語言其實一樣可以做到: 對 Perl,我們可以用Devel::DProf 模塊。你的程序應(yīng)該以perl -d:DProf mycode.pl來開始,并使用dprofpp來查看并分析結(jié)果。如果你可以用gcj 來編譯你的Java 程序,你也可以使用gprof,然而目前還只支持單線程的Java 代碼。

  結(jié)論

  就像我們已經(jīng)看到的,我們可以使用程序概要分析快速的找到一個程序里面值得優(yōu)化的地方。在值得優(yōu)化的地方優(yōu)化,我們可以將一個程序的運行時從 3分36秒 減少到少于 5秒,就像從上面的例子看到的一樣。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 临江市| 醴陵市| 广丰县| 米林县| 宜阳县| 会昌县| 林州市| 无锡市| 洛川县| 萍乡市| 盐池县| 通化县| 瑞安市| 宁化县| 临清市| 耒阳市| 饶河县| 东辽县| 沧州市| 嫩江县| 延川县| 正镶白旗| 乌审旗| 乐都县| 当涂县| 达孜县| 溧水县| 龙州县| 枝江市| 获嘉县| 林州市| 大田县| 阿尔山市| 长兴县| 磐石市| 贡嘎县| 许昌县| 淮北市| 京山县| 汝南县| 呼图壁县|