Linux 性能分析工具perf使用


 

Perf介紹

系統級性能優化通常包括兩個階段:性能剖析(performance profiling)和代碼優化。性能剖析的目標是尋找性能瓶頸,查找引發性能問題的原因及熱點代碼。代碼優化的目標是針對具體性能問題而優化代碼或編譯選項,以改善軟件性能。本篇主要講性能分析中常用的工具——perf。

perf是一款Linux性能分析工具。

它基於事件采樣原理,以性能事件為基礎,支持針對處理器相關性能指標與操作系統相關性能指標的性能剖析。常用於性能瓶頸的查找與熱點代碼的定位。

Linux性能計數器是一個新的基於內核的子系統,它提供一個性能分析框架,比如硬件(CPU、PMU(Performance Monitoring Unit))功能和軟件(軟件計數器、tracepoint)功能。通過perf,應用程序可以利用PMU、tracepoint和內核中的計數器來進行性能統計。它不但可以分析制定應用程序的性能問題(per thread),也可以用來分析內核的性能問題。

總之perf是一款很牛逼的綜合性分析工具,大到系統全局性性能,再小到進程線程級別,甚至到函數及匯編級別。

Perf基本原理

 perf的基本原理都是對被監測對象進行采樣,最簡單的情形是根據 tick 中斷進行采樣,即在 tick 中斷內觸發采樣點,在采樣點里判斷程序當時的上下文。

事件分為以下三種:

1)Hardware Event 是由 PMU 硬件產生的事件,比如 cache 命中,當您需要了解程序對硬件特性的使用情況時,便需要對這些事件進行采樣;

2)Software Event 是內核軟件產生的事件,比如進程切換,tick 數等 ;

3)Tracepoint event 是內核中的靜態 tracepoint 所觸發的事件,這些 tracepoint 用來判斷程序運行期間內核的行為細節,比如 slab 分配器的分配次數等。

CPU周期(cpu-cycles)是默認的性能事件,所謂的CPU周期是指CPU所能識別的最小時間單元,通常為億分之幾秒,是CPU執行最簡單的指令時所需要的時間,例如讀取寄存器中的內容,也叫做clock tick。

 

Perf使用

Perf是一個包含23種子工具的工具集
序號 命令 作用
1 annotate 解析perf record生成的perf.data文件,顯示被注釋的代碼。
2 archive 根據數據文件記錄的build-id,將所有被采樣到的elf文件打包。利用此壓縮包,可以再任何機器上分析數據文件中記錄的采樣數據。
3 bench perf中內置的benchmark,目前包括兩套針對調度器和內存管理子系統的benchmark。
4 buildid-cache 管理perf的buildid緩存,每個elf文件都有一個獨一無二的buildid。buildid被perf用來關聯性能數據與elf文件。
5 buildid-list 列出數據文件中記錄的所有buildid。
6 diff 對比兩個數據文件的差異。能夠給出每個符號(函數)在熱點分析上的具體差異。
7 evlist 列出數據文件perf.data中所有性能事件。
8 inject 該工具讀取perf record工具記錄的事件流,並將其定向到標准輸出。在被分析代碼中的任何一點,都可以向事件流中注入其它事件。
9 kmem 針對內核內存(slab)子系統進行追蹤測量的工具
10 kvm 用來追蹤測試運行在KVM虛擬機上的Guest OS。
11 list 列出當前系統支持的所有性能事件。包括硬件性能事件、軟件性能事件以及檢查點。
12 lock 分析內核中的鎖信息,包括鎖的爭用情況,等待延遲等。
13 mem 內存存取情況
14 record 收集采樣信息,並將其記錄在數據文件中。隨后可通過其它工具對數據文件進行分析。
15 report 讀取perf record創建的數據文件,並給出熱點分析結果。
16 sched 針對調度器子系統的分析工具。
17   執行perl或python寫的功能擴展腳本、生成腳本框架、讀取數據文件中的數據信息等。
18 stat 執行某個命令,收集特定進程的性能概況,包括CPI、Cache丟失率等。
19 test perf對當前軟硬件平台進行健全性測試,可用此工具測試當前的軟硬件平台是否能支持perf的所有功能。
20 timechart 針對測試期間系統行為進行可視化的工具
21 top 類似於linux的top命令,對系統性能進行實時分析。
22 trace 關於syscall的工具。
23 probe 用於定義動態檢查點。

全局性概況:

perf list查看當前系統支持的性能事件;

perf bench對系統性能進行摸底;

perf test對系統進行健全性測試;

perf stat對全局性能進行統計;

全局細節:

perf top可以實時查看當前系統進程函數占用率情況;

perf probe可以自定義動態事件;

特定功能分析:

perf kmem針對slab子系統性能分析;

perf kvm針對kvm虛擬化分析;

perf lock分析鎖性能;

perf mem分析內存slab性能;

perf sched分析內核調度器性能;

perf trace記錄系統調用軌跡;

最常用功能perf record,可以系統全局,也可以具體到某個進程,更甚具體到某一進程某一事件;可宏觀,也可以很微觀。

pref record記錄信息到perf.data;

perf report生成報告;

perf diff對兩個記錄進行diff;

perf evlist列出記錄的性能事件;

perf annotate顯示perf.data函數代碼;

perf archive將相關符號打包,方便在其它機器進行分析;

perf 將perf.data輸出可讀性文本;

可視化工具perf timechart

perf timechart record記錄事件;

perf timechart生成output.svg文檔;

以下是最常用的5種

perf top 類似系統命令 查看消耗cpu比較高的內核函數或者進程

對於一個指定的性能事件(默認是CPU周期),顯示消耗最多的函數或指令。

System profiling tool.

Generates and displays a performance counter profile in real time.

perf top [-e | --event=EVENT] []

perf top主要用於實時分析各個函數在某個性能事件上的熱度,能夠快速的定位熱點函數,包括應用程序函數、

模塊函數與內核函數,甚至能夠定位到熱點指令。默認的性能事件為cpu cycles。

使用例子

1、實時顯示占用 CPU 時鍾最多的函數或者指令(可以用來查找熱點函數)

# perf top
$ perf top
Samples: 833  of event 'cpu-clock', Event count (approx.): 97742399
Overhead  Shared Object       Symbol
   7.28%  perf                [.] 0x00000000001f78a4
   4.72%  [kernel]            [k] vsnprintf
   4.32%  [kernel]            [k] module_get_kallsym
   3.65%  [kernel]            [k] _raw_spin_unlock_irqrestore
...

輸出結果中,第一行包含三個數據,

  • 分別是采樣數(Samples)
  • 事件類型(event)
  • 事件總數量(Event count)。

比如這個例子中,perf 總共采集了 833 個 CPU 時鍾事件,而總事件數則為 97742399。

再往下看是一個表格式樣的數據,每一行包含四列,分別是:
  • 第一列 Overhead ,是該符號的性能事件在所有采樣中的比例,用百分比來表示。
  • 第二列 Shared ,是該函數或指令所在的動態共享對象(Dynamic Shared Object),如內核、進程名、動態鏈接庫名、內核模塊名等。
  • 第三列 Object ,是動態共享對象的類型。比如 [.] 表示用戶空間的可執行程序、或者動態鏈接庫,而 [k] 則表示內核空間。
  • 最后一列 Symbol 是符號名,也就是函數名。當函數名未知時,用十六進制的地址來表示。

2、-g開啟調用關系分析,-p指定的進程號21515

# perf top -g -p 21515

注意:使用方向鍵切換進程,再按下回車鍵展開某個進程的調用關系。

 

perf list 列出perf支持的事件

Perf ist用來查看perf所支持的性能事件,有軟件的也有硬件的。

List all symbolic event types.

perf list [hw | sw | cache | tracepoint | event_glob]

性能事件的分布

hw:Hardware event,9個

sw:Software event,9個

cache:Hardware cache event,26個

tracepoint:Tracepoint event,775個

sw實際上是內核的計數器,與硬件無關。

hw和cache是CPU架構相關的,依賴於具體硬件。

tracepoint是基於內核的ftrace,主線2.6.3x以上的內核版本才支持。

指定性能事件(以它的屬性)

-e : u // userspace

-e : k // kernel

-e : h // hypervisor

-e : G // guest counting (in KVM guests)

-e : H // host counting (not in KVM guests)

使用例子

1、顯示內核和模塊中,消耗最多CPU周期的函數:

# perf top -e cycles:k

2、顯示分配高速緩存最多的函數:

# perf top -e kmem:kmem_cache_alloc


perf stat 統計profiling進程的各種信息

用於分析指定程序的性能概況。

Run a command and gather performance counter statistics.

perf stat [-e | --event=EVENT] [-a]

perf stat [-e | --event=EVENT] [-a] - []

輸出格式

# perf stat ls

輸出包括ls的執行時間,以及10個性能事件的統計。

task-clock:任務真正占用的處理器時間,單位為ms。CPUs utilized = task-clock / time elapsed,CPU的占用率。

context-switches:上下文的切換次數。

CPU-migrations:處理器遷移次數。Linux為了維持多個處理器的負載均衡,在特定條件下會將某個任務從一個CPU

遷移到另一個CPU。

page-faults:缺頁異常的次數。當應用程序請求的頁面尚未建立、請求的頁面不在內存中,或者請求的頁面雖然在內

存中,但物理地址和虛擬地址的映射關系尚未建立時,都會觸發一次缺頁異常。另外TLB不命中,頁面訪問權限不匹配

等情況也會觸發缺頁異常。

cycles:消耗的處理器周期數。如果把被ls使用的cpu cycles看成是一個處理器的

可以用cycles / task-clock算出。

stalled-cycles-frontend:略過。

stalled-cycles-backend:略過。

instructions:執行了多少條指令。IPC為平均每個cpu cycle執行了多少條指令。

branches:遇到的分支指令數。branch-misses是預測錯誤的分支指令數。

常用參數

-p:stat events on existing process id (comma separated list). 僅分析目標進程及其創建的線程。

-a:system-wide collection from all CPUs. 從所有CPU上收集性能數據。

-r:repeat command and print average + stddev (max: 100). 重復執行命令求平均。

-C:Count only on the list of CPUs provided (comma separated list), 從指定CPU上收集性能數據。

-v:be more verbose (show counter open errors, etc), 顯示更多性能數據。

-n:null run - don't start any counters,只顯示任務的執行時間 。

-x SEP:指定輸出列的分隔符。

-o file:指定輸出文件,--append指定追加模式。

--pre :執行目標程序前先執行的程序。

--post :執行目標程序后再執行的程序。

使用例子

1、執行10次程序,給出標准偏差與期望的比值:

# perf stat -r 10 ls > /dev/null

2、顯示更詳細的信息:

# perf stat -v ls > /dev/null

3、只顯示任務執行時間,不顯示性能計數器:

# perf stat -n ls > /dev/null

4、單獨給出每個CPU上的信息:

# perf stat -a -A ls > /dev/null

5、ls命令執行了多少次系統調用:

# perf stat -e syscalls:sys_enter ls

perf record profiling進程的數據,並生成 xx.data文件(默認在執行命令的路徑下)

收集采樣信息,並將其記錄在數據文件中。

隨后可以通過其它工具(perf-report)對數據文件進行分析,結果類似於perf-top的。

常用參數

-e:Select the PMU event.

-a:System-wide collection from all CPUs.

-p:Record events on existing process ID (comma separated list).

-A:Append to the output file to do incremental profiling.

-f:Overwrite existing data file.

-o:Output file name.

-g:Do call-graph (stack chain/backtrace) recording.

-C:Collect samples only on the list of CPUs provided.

使用例子

1、記錄性能事件,等待大約15秒后按 Ctrl+C 退出

# perf record -g

2、記錄nginx進程的性能數據:

# perf record -p `pgrep -d ',' nginx`

3、記錄執行ls時的性能數據:

# perf record ls -g

4、記錄執行ls時的系統調用,可以知道哪些系統調用最頻繁:

# perf record -e syscalls:sys_enter ls

 

perf report 讀取xx.data文件

讀取perf record創建的數據文件,並給出熱點分析結果。
使用例子
1、查看報告
# perf report
 
 
火焰圖
 
使用perf record記錄采樣數據

perf record -e cpu-clock -g -p 4522

使用ctrl+c中斷perf進程,或者在程序執行結束后,會產生perf.data的文件,使用report會產生結果分析,如圖
perf report
在這里插入圖片描述

上面通過文件查看不夠直觀,還有一種火焰圖分析的方式:
工具下載:
git clone https://github.com/brendangregg/FlameGraph.git
使用命令:

使用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

然后可以通過chrome或者看圖軟件打開:
r

Y軸表示調用棧,X軸越寬,就表示它被抽到的次數多,即執行的時間長。注意,x 軸不代表時間,而是所有的調用棧合並后,按字母順序排列的。

所以,一般我們只需要看有沒有出現 “平頂”,如果有,那么這個函數可能有性能問題。

 
refer:
https://www.jianshu.com/p/675a850365eb
https://www.sohu.com/a/292825608_467784


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM