Perf 性能分析指南

安裝

在開發板上使用 apt 安裝 perf 命令:

apt install -y perf

或者進入kernel內核源碼目錄tools/perf,交叉編譯執行make,然後拷貝到開發板中運行。

認識 Perf

perf可以用來統計一個程序運行期間花了多少時間、上下文切換次數、cache 命中率等一些性能相關的事件,通過 perf 可以分析一個程序的性能瓶頸,從而對程序做出優化。

perf 性能事件的關係圖如下:

執行命令:

perf list

可以看到如下顯示:

branch-instructions OR branches                    [Hardware event]
branch-misses                                      [Hardware event]
cache-misses                                       [Hardware event]
... ...

context-switches OR cs                             [Software event]
page-faults OR faults                              [Software event]
... ...

L1-dcache-load-misses                              [Hardware cache event]
L1-dcache-loads                                    [Hardware cache event]
... ...

block:block_bio_backmerge                          [Tracepoint event]
clk:clk_enable                                     [Tracepoint event]
dma_fence:dma_fence_destroy                        [Tracepoint event]
... ...

其中

perf的性能事件主要可以分爲以上四類,但是像hardware event這類事件依賴於硬件的實現,如果硬件不支持也無法統計。部分的其它事件在使用的過程也會遇到不支持的情況。

另外執行perf list命令並不會把所有的事件都列舉出來,perf list只會顯示支持的事件,如果不支持就看不到了。

Perf 功能概覽

perf的功能可以分爲基礎子命令功能型子命令兩大類。

基礎子命令是最常用的命令,是必須要學會的。

基礎子命令如下

功能型子命令如下

更多的命令詳細參考perf -h說明。

Perf 基礎子命令

perf list

perf list 可以列舉支持哪些事件:

perf stat

perf stat可以採樣perf list所列舉的事件,使用幫助如下:

perf stat -h
-a, --all-cpus        system-wide collection from all CPUs
-A, --no-aggr         disable CPU count aggregation
-B, --big-num         print large numbers with thousands' separators
-C, --cpu <cpu>       list of cpus to monitor in system-wide
-D, --delay <n>       ms to wait before starting measurement after program start (-1: start with events disabled)
-d, --detailed        detailed run - start a lot of events
-e, --event <event>   event selector. use 'perf list' to list available events
-G, --cgroup <name>   monitor event in cgroup name only
-g, --group           put the counters into a counter group
... ...

perf stat可以通過-e指定某個事件,例如統計ls命令的cpu-clock事件:

對於tracepoint event事件,其本身就分爲很多種類型,例如:block:block_bio_backmerge,就表示block這個類型的block_bio_backmerge這個採樣點。

tracepoint event支持採樣類型和採樣點非常多,有clkmmcsched等類型,而其中每個採樣類型又分爲更多的採樣點,因此,可以通過perf list後面跟上採樣類型的名字,來查看某個特性類型的採樣點。

可以看到,一個sched類型,對應很多采樣點。

對應着sched:sched_switch這個採樣點。通過perf stat子命令可以得到觀測結果:

可以看到,執行lscpu運行了29sched_switch,也就是對應的__schedule 函數。

其實tracepoint event最強大的地方在於時間的統計,內核中每個採樣點都代表了一些重要的時刻,比如,進程切換了,調度器把進程放入runqueue,或者開始真正的進程運行,都會加上一個tracepoint,來記錄時間,從而爲分析和調試提供支持。

perf record & perf report

perf stat子命令展示的是即時的數據,若想要獲取更多信息,則需要用perf record子命令將信息組成一個perf.data文件,並利用perf report將其解析並展示出來。

因此perf recordperf report命令通常是一起使用的。

同樣的,perf recordperf report子命令也具有相當多的參數。

perf report -h
-b, --branch-stack    use branch records for per branch histogram filling
-c, --comms <comm[,comm...]>
only consider symbols in these comms
-C, --cpu <cpu>       list of cpus to profile
... ...

例如對context-switches事件採樣:

perf record -e context-switches -a sleep 1

然後執行perf report顯示更多的詳細信息:

可以看到,perf report子命令不光展示了cpu執行sleep 1時發生的上下文切換次數,還展示了這切換都分佈在哪些進程中。

perf script

perf script主要被用來生成perf.unfold文件,被交給一個名叫FlameGraph火焰圖)的工具,這個工具會解析 perf.unfold 數據,然後將其轉換成易於人類閱讀和分析的圖形。

火焰圖

wget "https://github.com/brendangregg/FlameGraph/archive/master.zip"
unzip master.zip

如果希望瞭解 CPU 在一段時間內的都運行了哪些函數以及各函數都消耗了多少時間,就可以使用 On CPU 火焰圖,這種火焰圖基於cpu-cycles事件進行採樣,然後通過svg圖片格式展現出來

dd if=/dev/zero of=/tmp/testfile bs=4K count=102400 &
perf record -e cpu-cycles -a -g sleep 1
perf script > perf.unfold
cd FlameGraph-master
./stackcollapse-perf.pl < ../perf.unfold | ./flamegraph.pl > ../perf.svg

首先在後臺啓動一個dd命令,讓它持續運行一段時間,然後開啓perf record,記錄一秒鐘內cpu都運行了多少個cpu-cycles,也就是時間(同時使能-g,就會一併記錄運行的函數以及調用關係),再利用perf script命令將perf.data轉成perf.unfold,最後利用FlameGraph工具將其轉換成一個perf.svg,這是一個圖形文件,用瀏覽器打開後會得到這樣一幅圖:

此圖記錄着函數調用關係及其 cpu-cycles(時間)佔比,就像一縷縷升起的火苗,所以被稱之爲火焰圖。

火焰圖還可以通過鼠標點擊放大,觀察其細節,如下:

Perf 功能型子命令

列舉 2 個perf功能型子命令實例topbench,更多的參考-h列舉的說明。

perf top

perf top子命令動態地顯示各種採樣事件,例如:

perf top -e sched:sched_wakeup

perf bench

perf bench子命令是perf內部集成的一個benchmark測試程序,可以看一下perf bench支持哪些benchmark

可見,benchmarkschedmem, futex等幾大類

perf bench mem

mem裏又包含了 2 個測試點

perf bench mem memcpy

perf bench mem memset

總結

perf 是用於性能分析的一個工具,功能強大,用法也非常多。但是要真正用明白,懂得分析,需要長時間的學習和沉澱。

例如必須得知道cyclesinstructions分支預測等這些是什麼意思,每個性能事件的統計值高低所帶來的影響分別是什麼,如何增加 / 降低某個性能事件的統計值等等,只有在具備這些理論基礎的情況下,去分析 perf 的統計值才比較有意義。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/TJIy9fvCJPjeVwWzjkJyxw