效能工具perf的用法以及如何繪製效能火焰圖
perf簡介
Perf是內建於Linux核心原始碼樹中的效能剖析(profiling)工具。其基於事件取樣原理,以效能事件為基礎,常用於效能瓶頸的查詢與熱點程式碼的定位。
效能調優工具如 perf,Oprofile 等的基本原理都是對被監測物件進行取樣,最簡單的情形是根據 tick 中斷進行取樣,即在 tick 中斷內觸發取樣點,在取樣點裡判斷程式當時的上下文。假如一個程式 90% 的時間都花費在函式 foo() 上,那麼 90% 的取樣點都應該落在函式 foo的上下文中。只要取樣頻率足夠高,取樣時間足夠長,那麼以上推論就比較可靠。因此,通過 tick 觸發取樣,我們便可以瞭解程式中哪些地方最耗時間,從而重點分析。
稍微擴充套件一下思路,就可以發現改變取樣的觸發條件使得我們可以獲得不同的統計資料:
- 以時間點 ( 如 tick) 作為事件觸發取樣便可以獲知程式執行時間的分佈。
- 以 cache miss 事件觸發取樣便可以知道 cache miss 的分佈,即 cache 失效經常發生在哪些程式程式碼中
- 等等其他事件
當然,perf使用更多是CPU的PMU計數器,PMU計數器是大部分CPU都有的功能,它們可以用來統計比如L1 Cache失效的次數,分支預測失敗的次數等。PMU可以在這些計數器的計數超過一個特定的值的時候產生一箇中斷,這個中斷,我們可以用和時鐘一樣的方法,來抽樣判斷系統中哪個函式發生了最多的Cache失效,分支預測失效等。
perf 用法
本文示例程式碼:
//
// Created by wilcohuang on 2018/11/19.
//
#include <unistd.h>
using namespace std;
#define NUM 500000
void 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);
}
說明
perf的使用可以分為兩種方式:
- 直接使用perf啟動服務
- 掛接到已啟動的程式
第一種方式不需要root許可權,第二種方式需要root許可權
perf top
用於檢視cpu的主要效能消耗點
跟蹤一個名為main的程式:
perf top -e cycles -p `pgrep main`
輸入如下:
perf record
同樣是分析診斷程式:
perf record -e cpu-clock -g ./run
或者
perf record -e cpu-clock -g -p 4522
使用ctrl+c中斷perf程式,或者在程式執行結束後,會產生perf.data的檔案,使用
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或者看圖軟體開啟:
Y軸表示呼叫棧,X軸越寬,就表示它被抽到的次數多,即執行的時間長。注意,x 軸不代表時間,而是所有的呼叫棧合併後,按字母順序排列的。
所以,一般我們只需要看有沒有出現 “平頂”,如果有,那麼這個函式可能有效能問題。
perf diff
優化程式效能後,我們自然要看下效果:
perf diff perf.data perf.data.before
我們幹掉了上文中的usleep(3);
這句程式碼,然後diff結果輸出如下:
init、accu函式的時間佔比已經將為了0 ?
許可權問題
perf如果不是root,你可以做什麼取決於sysctl設定。kernel.perf_event_paranoid
cat /proc/sys/kernel/perf_event_paranoid
kernel.perf_event_paranoid= 2:您無法進行任何測量。該perf實用程式可能仍然是有用的分析現有的記錄用perf ls,perf report,perf timechart或perf trace。
kernel.perf_event_paranoid= 1:您可以使用perf stator 跟蹤命令perf record,並獲取核心分析資料。
kernel.perf_event_paranoid= 0:您可以使用perf stat或跟蹤命令perf record,並獲取CPU事件資料。
kernel.perf_event_paranoid= -1:您獲得了對核心跟蹤點的原始訪問許可權(具體來說,您可以mmap建立檔案perf_event_open,我不知道其含義是什麼)。
參考
更全的perf參考:
本文參考:
相關文章
- perf及火焰圖的使用,效能分析
- linux 效能調優工具perf + 火焰圖 常用命令Linux
- perf/Simpleperf 生成火焰圖
- linux效能分析工具之火焰圖Linux
- perf效能分析工具使用分享
- perf 的資料用火焰圖顯示
- 如何利用工具提高React頁面渲染效能之PerfReact
- Flame Graph 火焰圖分析 Java 效能Java
- go效能調優之火焰圖Go
- Linux下用perf生成火焰圖方法Linux
- Linux程式效能分析和火焰圖Linux
- JAVA效能分析之使用火焰圖Java
- Nagios整合pnp繪製效能分析圖表iOS
- 系統級效能分析工具perf的介紹與使用
- openresty使用火焰圖排查效能問題REST
- 如何讀懂火焰圖?+ 例項講解程式效能優化優化
- 網路效能測試-perf
- 利用perf進行效能分析
- Android繪製優化(一)繪製效能分析Android優化
- 如何繪製漂亮的架構圖,方法論+工具架構
- 如何製作室內地圖,室內地圖繪製工具地圖
- Linux火焰圖效能分析文章及視訊演示Linux
- 使用火焰圖進行Java應用效能分析Java
- EazyDraw 向量圖繪製工具
- 宋寶華:火焰圖 全域性視野的 Linux 效能剖析Linux
- 效能優化(二) UI 繪製優化優化UI
- 程式設計師精進之路:效能調優利器--火焰圖程式設計師
- 如何繪製Wardley地圖?地圖
- oracle 10g awr效能收集工具的用法Oracle 10g
- 容器化 RDS:藉助火焰圖定位Kubernetes效能問題
- MiniProfiler效能分析工具— .Net Core中用法
- 如何繪製業務流程圖(二)流程圖
- Rust效能分析之測試及火焰圖,附(lru,lfu,arc)測試Rust
- 如何使用軟體繪製流程圖!流程圖
- 使用joinjs繪製流程圖(五)-流程圖繪製JS流程圖
- iOS 繪圖 - 如何繪製一個多邊形能力分佈圖iOS繪圖
- 繪圖工具繪圖
- Oracle效能圖表工具:awrcrt.sqlOracleSQL