歡迎你們前往騰訊雲+社區,獲取更多騰訊海量技術實踐乾貨哦~。python
做者:趙坤|騰訊魔王工做室後臺開發工程師linux
在項目開發中,常常會遇到程序啓動時間過長、CPU使用率太高等問題,這個時候須要依靠性能分析工具來定位性能的消耗點。本文介紹三個經常使用的工具的入門級使用及圖形化方法,供你們參考。git
本文介紹Perf、gprof和Valgrind三個性能分析工具,及其分析結果圖形化的方法,旨在讓你們更快的上手使用工具。出於篇幅的限制,本文不會對每種工具的使用參數及結果分析作詳細的介紹,只作入門級的使用說明,更多詳細的說明你們請Google一下。github
每一個工具的介紹會分紅簡介、使用說明、圖形化方法三個部分。算法
每種工具的結果都會基於下面這段代碼:windows
#include <unistd.h>using namespace std;#define NUM 500000void init(int* int_array){ for(int i=0;i<NUM;i++){ int_array[i]=i; }}void accu(int* int_array,long& sum ){ for(int i=0;i<NUM;i++){ sum+=int_array[i]; usleep(3); }}int main(){ int int_array[NUM]; init(int_array); long sum=0; accu(int_array,sum);}
這段代碼在普通PC上執行了31s,最大CPU使用率爲8.3%性能優化
Perf是內置於Linux內核源碼樹中的性能剖析(profiling)工具。其基於事件採樣原理,以性能事件爲基礎,經常使用於性能瓶頸的查找與熱點代碼的定位。服務器
perf的使用能夠分爲兩種方式:多線程
直接使用perf啓動服務svg
掛接到已啓動的進程
第一種方式不須要root權限,第二種方式須要root權限
基於入門級使用這一前提,直接介紹一下使用方式:
perf record -e cpu-clock -g ./run 或者 perf record -e cpu-clock -g -p 4522
使用ctrl+c中斷perf進程,或者在程序執行結束後,會產生perf.data的文件,使用
perf report
會產生結果分析,如圖
perf的結果能夠生成火焰圖。生成火焰圖須要藉助Flame Graph
Flame Graph項目位於GitHub:
https://github.com/brendangregg/FlameGraph
clone代碼或者直接下載壓縮包到服務器上。以壓縮包爲例,是一個命名爲:FlameGraph-master.zip的文件,假設其解壓後的目錄爲:/data
基於1.2產生的perf.data,後續步驟以下:
一、使用perf script工具對perf.data進行解析perf script -i perf.data &> perf.unfold 二、將perf.unfold中的符號進行摺疊:/data/stackcollapse-perf.pl perf.unfold &> perf.folded 三、最後生成svg圖:/data/flamegraph.pl perf.folded > perf.svg
生成的火焰圖以下:
關於火焰圖的含義及分析網上有不少文章,這裏再也不贅述
gprof用於監控程序中每一個方法的執行時間和被調用次數,方便找出程序中最耗時的函數。在程序正常退出後,會生成gmon.out文件,解析這個文件,能夠生成一個可視化的報告
使用gprof,須要在編譯時,加入-pg選項
另外只有在程序正常退出後纔會生成gmon.out,kill進程的方法是無法生成gmon.out的。對於那些線程會一直run的服務,須要修改代碼,讓程序在某個時間點中止。
從新編譯後,正常啓動程序便可;而後在程序運行結束後,會生成gmon.out文件
使用以下命令,生成報名文件(其中run是二進制的名字):
gprof -b run gmon.out >>report.txt
report.txt打開以下圖所示:
gprof的結果文件須要藉助gprof2dot.py和graphviz來展現
使用gprof2dot.py生成dot文件
python gprof2dot.py report.txt >report.dot
須要說明的是,這裏要求服務器已經安裝了python,而且要求gprof2dot.py與安裝的python版本匹配。這二者是否匹配是一個須要運氣、而且解決起來很無聊的事情,個人服務器上安裝的python是2.6.6,第一次從網上下載的gprof2dot-2017.9.19與python版本就不匹配,執行會出錯。目前使用的版本與2.6.6是兼容的,若是須要能夠與我聯繫。
dot的打開須要graphviz工具,我是在windows下安裝的graphviz,這個工具下載很簡單。下載後使用gvedit.ext打開前一個步驟產生的report.dot文件便可
這個圖顯的有些萌萌噠,這是由於咱們的程序寫的比較簡單,對於通常的業務而言,這個圖會比較複雜。
valgrind不是linux的原生工具,須要自行安裝。valgrind自身包含了多個工具:
Memcheck:用於內存泄漏檢查
Callgrind:用於性能分析,會收集程序運行時間和調用關係
以及Cachegrind、Helgrind等
這裏咱們主要使用的Callgrind工具
首先須要安裝valgrind:
http://valgrind.org/downloads/valgrind-3.12.0.tar.bz2
解壓安裝包後,順次執行:./configue 、make、make install 就能夠了
使用valgrind來分析性能,必須使用valgrind來啓動程序:
valgrind --tool=callgrind --separate-threads=yes ./run
--separate-threads是指是否按線程來分別統計,若是不加,會將全部線程的結果打到一個文件裏;不然會按線程分別打印到不一樣文件裏。
程序執行結束後,會生成形如:callgrind.out.4263-01的文件。這個文件直接分析起來有些困難,必須藉助圖形化的方式來瀏覽
valgrind的圖形化須要藉助kcachegrind.exe,你們能夠自行下載,下載後在windows運行便可。這是打開callgrind.out.4263-01的結果:
對於咱們的需求:定位執行時間最長、佔用CPU最多的函數 來講,這三個工具均可以達到目的。但這三者之間仍是有必定的差距:
Perf雖然能夠掛接進程但須要root權限。在普通權限下,Perf和Valgrind必須使用前綴啓動的方式來啓動程序,這在某種程度上會影響到程序的性能。咱們在壓測的過程當中發現使用Valgrind啓動的時候,能夠支持的在線總人數比直接運行程序要少不少。
Perf和Valgrind都不須要修改Makefile或者程序,但gprof須要從新編譯文件,而且對於線程一直run的服務,還須要修改代碼讓其天然退出,這在必定程序上侵入了程序。但從對性能影響上來看,gprof能夠最大限制的保留原程序的性能
gprof的結果是一顆倒樹,這顆樹展現了從根到葉子的全部結點的時間消耗;perf的是一個金字塔,與gprof有殊途同歸之妙;Valgrind的結果是一條單路,指出的是某條調用路徑上的時間消耗,並非一個全局的展現。
這是一個很專業的話題,目前對三者的監控原理尚未摸的太透,因此這裏暫時空着。你們有興趣能夠先行研究。
問答
相關閱讀
此文已由做者受權騰訊雲+社區發佈,轉載請註明文章出處
原文連接:https://cloud.tencent.com/developer/article/1063652