Linux效能分析工具與圖形化方法

騰訊雲加社群發表於2018-03-16

歡迎大家前往騰訊雲+社群,獲取更多騰訊海量技術實踐乾貨哦~。

作者:趙坤|騰訊魔王工作室後臺開發工程師

在專案開發中,經常會遇到程式啟動時間過長、CPU使用率過高等問題,這個時候需要依靠效能分析工具來定位效能的消耗點。本文介紹三個常用的工具的入門級使用及圖形化方法,供大家參考。

本文介紹Perf、gprof和Valgrind三個效能分析工具,及其分析結果圖形化的方法,旨在讓大家更快的上手使用工具。出於篇幅的限制,本文不會對每種工具的使用引數及結果分析做詳細的介紹,只做入門級的使用說明,更多詳細的說明大家請Google一下。

每個工具的介紹會分成簡介、使用說明、圖形化方法三個部分。

每種工具的結果都會基於下面這段程式碼:

#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%

Perf1.1 簡介

Perf是內建於Linux核心原始碼樹中的效能剖析(profiling)工具。其基於事件取樣原理,以效能事件為基礎,常用於效能瓶頸的查詢與熱點程式碼的定位。

1.2 使用

perf的使用可以分為兩種方式:

  1. 直接使用perf啟動服務

  2. 掛接到已啟動的程式

第一種方式不需要root許可權,第二種方式需要root許可權

基於入門級使用這一前提,直接介紹一下使用方式:

perf record -e cpu-clock -g ./run
或者
perf record -e cpu-clock -g -p 4522複製程式碼

使用ctrl+c中斷perf程式,或者在程式執行結束後,會產生perf.data的檔案,使用

perf report複製程式碼

會產生結果分析,如圖

1.3 圖形化方法

perf的結果可以生成火焰圖。生成火焰圖需要藉助Flame Graph

Flame Graph專案位於GitHub:

https://github.com/brendangregg/FlameGraph

clone程式碼或者直接下載壓縮包到伺服器上。以壓縮包為例,是一個命名為:FlameGraph-master.zip的檔案,假設其解壓後的目錄為:/data

基於1.2產生的perf.data,後續步驟如下:

1、使用perf script工具對perf.data進行解析perf script -i perf.data &> perf.unfold
2、將perf.unfold中的符號進行摺疊:/data/stackcollapse-perf.pl perf.unfold &> perf.folded
3、最後生成svg圖:/data/flamegraph.pl perf.folded > perf.svg複製程式碼

生成的火焰圖如下:

關於火焰圖的含義及分析網上有很多文章,這裡不再贅述

Gprof2.1 簡介

gprof用於監控程式中每個方法的執行時間和被呼叫次數,方便找出程式中最耗時的函式。在程式正常退出後,會生成gmon.out檔案,解析這個檔案,可以生成一個視覺化的報告

2.2 使用方法

使用gprof,需要在編譯時,加入-pg選項

另外只有在程式正常退出後才會生成gmon.out,kill程式的方法是沒法生成gmon.out的。對於那些執行緒會一直run的服務,需要修改程式碼,讓程式在某個時間點停止。

重新編譯後,正常啟動程式即可;然後在程式執行結束後,會生成gmon.out檔案

使用如下命令,生成報名檔案(其中run是二進位制的名字):

gprof -b run gmon.out >>report.txt複製程式碼

report.txt開啟如下圖所示:

2.3 圖形化方法

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檔案即可

這個圖顯的有些萌萌噠,這是因為我們的程式寫的比較簡單,對於一般的業務而言,這個圖會比較複雜。

Valgrind3.1 簡介

valgrind不是linux的原生工具,需要自行安裝。valgrind自身包含了多個工具:

  • Memcheck:用於記憶體洩漏檢查

  • Callgrind:用於效能分析,會收集程式執行時間和呼叫關係

  • 以及Cachegrind、Helgrind等

這裡我們主要使用的Callgrind工具

3.2 使用方法

首先需要安裝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的檔案。這個檔案直接分析起來有些困難,必須藉助圖形化的方式來瀏覽

3.3 圖形化方法

valgrind的圖形化需要藉助kcachegrind.exe,大家可以自行下載,下載後在windows執行即可。這是開啟callgrind.out.4263-01的結果:

4工具比較

對於我們的需求:定位執行時間最長、佔用CPU最多的函式 來說,這三個工具都可以達到目的。但這三者之間還是有一定的差距:

4.1 啟動方式

Perf雖然可以掛接程式但需要root許可權。在普通許可權下,Perf和Valgrind必須使用字首啟動的方式來啟動程式,這在某種程度上會影響到程式的效能。我們在壓測的過程中發現使用Valgrind啟動的時候,可以支援的線上總人數比直接執行程式要少很多。

4.2 程式侵入

Perf和Valgrind都不需要修改Makefile或者程式,但gprof需要重新編譯檔案,並且對於執行緒一直run的服務,還需要修改程式碼讓其自然退出,這在一定程式上侵入了程式。但從對效能影響上來看,gprof可以最大限制的保留原程式的效能

4.3 結果展示

gprof的結果是一顆倒樹,這顆樹展示了從根到葉子的所有結點的時間消耗;perf的是一個金字塔,與gprof有異曲同工之妙;Valgrind的結果是一條單路,指出的是某條呼叫路徑上的時間消耗,並不是一個全域性的展示。

4.4 監控原理

這是一個很專業的話題,目前對三者的監控原理還沒有摸的太透,所以這裡暫時空著。大家有興趣可以先行研究。

問答

linux實時排程演算法?

Linux中的多執行緒處理?

相關閱讀

Linux 常用效能工具簡介

常見Linux調優命令和工具

效能優化:Linux環境下合理配置大記憶體頁

此文已由作者授權騰訊雲+社群釋出,轉載請註明文章出處

原文連結:https://cloud.tencent.com/developer/article/1063652


相關文章