• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 使用GProf來優化你的C/C++程序

    發表于:2007-07-04來源:作者:點擊數: 標簽:
    從其他地方轉過來的文章,但是想不起從哪兒轉的了,呵呵 如果有人看到了,并且是不允許轉的,請留言,thx by Arnout Engelen arnouten(Q)bzzt.net 關于作者: Arnout Engelen 是荷蘭Nijmegen大學計算機系的學生,也是 網絡 安全公司T UNIX 的雇員。在空閑時間
    從其他地方轉過來的文章,但是想不起從哪兒轉的了,呵呵
    如果有人看到了,并且是不允許轉的,請留言,thx


    by Arnout Engelen
    <arnouten(Q)bzzt.net>

    關于作者:

    Arnout Engelen 是荷蘭Nijmegen大學計算機系的學生,也是網絡安全公司TUNIX的雇員。在空閑時間,他喜歡長跑和吹奏高音薩克斯。


    目錄:
    • Profiling in a nutshell
    • 案例分析: Pathalizer
    • 給程序計時
    • 程序分析
    • 優化
    • 結果
    • 第二遍
    • 其他 C/C++ 程序分析器
    • 對其他語言的程序進行分析
    • 結論
    • References
    • 對這篇文章發表評論

     

    使用GProf來優化你的C/C++程序

    摘要:

    在優化程序的時候,要記?。涸谥档脙灮牡胤絻灮?!沒有必要花上幾個小時來優化一段實際上只運行0.04秒的程序。

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

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

    _________________ _________________ _________________

     

    Profiling in a nutshell

    程序概要分析的概念非常簡單:通過記錄各個函數的調用和結束時間,我們可以計算出程序的最大運行時的程序段。這種方法聽起來似乎要花費很多氣力——幸運的是,我們其實離真理并不遠!我們只需要在用 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

    現在我們可以再次運行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
     

    其他 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.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>