Linux使用perf分析CPU占用情況的方法步驟
1. 如何使用perf工具
1.1 perf安裝
perf安裝命令:
sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y sudo apt-get install linux-tools-$(uname -r) linux-tools-generic -y --fix-missing perf -v # 查看perf版本
1.2 首次使用perf報錯
No permission to enable cycles: u event
解決方法:直接修改 /proc/sys/kernel/perf_event_paranoid,按照報錯提示修改為 -1
如果是docker容器環(huán)境提示 read only file system, 新建容器的時候應該添加 privileged=true 賦予權限
1.3 添加測試程序
新建并添加測試程序如下,輸入代碼
touch main.cpp vim main.cpp
#include <iostream> using namespace std; void delay() { int i,j; for(i = 0; i < 1000000; i++) j=i; } void function_1() { int i; for(i=0 ; i < 10; i++) delay(); } void function_2() { int i; for(i = 0; i< 30; i++) delay(); } int main(void) { std::cout << "begin: " << std::endl; function_1(); function_2(); std::cout << "end!" << std::endl; }
1.4 編譯并執(zhí)行指令生成perf.data文件
編譯測試程序
g++ main.cpp -o main
生成perf.data
sudo perf record ./main
1.5 添加-g選項能查看call graph調用信息
添加-g選項查看調用信息
sudo perf record -g ./main
1.6 查看perf.data
生成熱點函數(shù)占用CPU的比例
perf report
可以看到, 程序中main函數(shù)總體CPU資源占比(CPU時間片)97.85%, 其中delay函數(shù)占比97.59%, function_1和function_2的占比占比近7:3
1.7 perf工作流
1.8 sudo perf record -F 99 -p 2512 -g – sleep 60
- record: 表示采集系統(tǒng)事件,沒有采用-e執(zhí)行采集事件,則默認采用CPU時鐘周期
- -F: 指定采樣頻率, 可以設置99, 1000等等, -F 99表示每秒采樣99次, 如果99次都是同一函數(shù), 說明CPU在這1s內都在執(zhí)行這一函數(shù), 可能存在性能問題. 頻率越高,perf record獲得的樣本數(shù)量也會越多,分析結果會更加精細,但采樣會使程序的運行變慢,因此需要根據(jù)具體情況選擇合適的采樣頻率; 默認頻率4000Hz
- -p: 指定進程號, 對某一進程進行分析
- -g: 表示記錄調用棧, 拿到程序的call graph信息
- --sleep 60: 表示對進程持續(xù)分析60s
2. 如何生成火焰圖
2.1 安裝火焰圖生成工具
Flame Graph工程實現(xiàn)了一套生成火焰圖的腳本, 直接clone下來使用
git clone https://github.com/brendangregg/FlameGraph.git
該文件夾下有很多perf語言腳本, 可完成不同堆棧分析
2.2 生成和創(chuàng)建火焰圖的步驟
捕獲堆棧: perf script -i perf.data &> perf.unfold
折疊堆棧: ./FlameGraph/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
生成火焰圖: ./FlameGraph/FlameGraph/flamegraph.pl perf.folded > perf.svg
各個步驟的含義:
- 捕獲堆棧: 可以使用 perf、systemtap、dtrace 等工具抓取程序的運行堆棧
- 折疊堆棧: 對捕獲的堆棧信息進行分析組合, 將重復的堆棧累計在一起, 從而體現(xiàn)出負載和關鍵路徑, 由FlameGraph的stackcollapse程序生成, 注意程序路徑
- 生成火焰圖: 分析由stackcollapse輸出的堆棧信息的火焰圖, 執(zhí)行完后生成.svg圖片
2.3 火焰圖的含義
y軸表示調用棧,每一層都是一個函數(shù)。調用棧越深,火焰就越高,頂部就是正在執(zhí)行的函數(shù),下方都是它的父函數(shù)
x軸表示抽樣數(shù),如果一個函數(shù)在x軸占據(jù)的寬度越寬,就表示它被抽到的次數(shù)多,即執(zhí)行的時間占比越大。注意,x軸不代表時間,而是所有的調用棧合并后,按字母順序排列的
顏色無特殊含義, 因為火焰圖表示CPU的繁忙程度, 所以一般選擇暖色調
火焰圖就是看頂層的哪個函數(shù)占據(jù)的寬度最大。只要有"平頂",就表示該函數(shù)可能存在性能問題
鼠標懸浮: (瀏覽器打開.svg圖片)可顯示函數(shù)名, 抽樣抽中的次數(shù), 占總抽樣次數(shù)的百分比
點擊放大: 點擊某一層,該層會占據(jù)所有寬度,顯示詳細信息,再點擊左上角ResetZoom可恢復
查找: Ctrl + F, 高亮顯示查找的函數(shù)
火焰圖的缺陷: 調用??赡懿煌暾? 當調用棧過深時,某些系統(tǒng)只返回前面的一部分(比如前10層); 函數(shù)名可能缺失, 有些函數(shù)沒有名字,編譯器只用內存地址來表示(比如匿名函數(shù)), 有可能是編譯器優(yōu)化等級過高
FlameGraph我們習慣稱之為"CPU火焰圖", 還有"瀏覽器火焰圖"(x軸是任務時間軸), “紅/藍差分火焰圖”, 紅藍差分火焰圖可以用來對比分析兩次修改的性能差異, 紅色表示上升, 藍色表示下降, 由此來尋找根因; 此外還有"Memory Flame Graphs"(檢測內存占用量增加的原因), “Off-CPU Flame Graphs”(不在CPU上運行的時間,如I/O時間等), “Hot/Cold Flame Graphs”(CPU和非CPU結合,顯示所有線程的運行時間)
2.4 生成"紅/藍差分火焰圖"示例
修改源程序
#include <iostream> using namespace std; void delay() { int i,j; for(i = 0; i < 1000000; i++) j=i; } void function_1() { int i; for(i=0 ; i < 20; i++) delay(); } void function_2() { int i; for(i = 0; i< 20; i++) delay(); } int main(void) { std::cout << "begin: " << std::endl; function_1(); function_2(); std::cout << "end!" << std::endl; }
重新編譯執(zhí)行
g++ main.cpp -o main sudo perf record -g ./main # 生成新的perf.data
折疊堆棧
perf script -i perf.data &> perf.unfold # 生成新的perf.unfold ./FlameGraph/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded1
生成火焰圖
./FlameGraph/FlameGraph/flamegraph.pl perf.folded1 > perf2.svg
以perf.folded為基準,生成差分火焰圖
./FlameGraph/FlameGraph/difffolded.pl perf.folded perf.folded1 | ./FlameGraph/FlameGraph/flamegraph.pl > diff.svg
瀏覽器打開diff.svg
紅色部分表示function_1中delay耗時增加了, 藍色部分表示function_2中delay耗時減少了, 和我們修改的預期是一樣的
3. 使用perf分析節(jié)點CPU占比
執(zhí)行報錯1:sudo perf record -g ./可執(zhí)行文件, 執(zhí)行失敗。節(jié)點編譯完成后報錯找不到
error while loading shared libraries: liblibstatistics_collector.so
解決方法:搜索發(fā)現(xiàn)liblibstatistics_collector.so存在, 但通過export添加路徑后不生效
- export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/so_path 執(zhí)行后不管用
- sudo ldconfig # 動態(tài)鏈接庫管理, 讓不同目錄下的動態(tài)鏈接庫為系統(tǒng)所共享
- 或者試下 ldconfig 然后 perf record -g ./可執(zhí)行文件, 不要加sudo
- 執(zhí)行后生效
執(zhí)行報錯2:上一步生成的perf.data執(zhí)行perf report提示文件size field is 0
data size field is 0 which is unexpected
原因分析:看下來是perf record -g ./可執(zhí)行文件的形式?jīng)]有正確生成perf.data, 單獨執(zhí)行perf record進行采樣
top # 查看程序PID = 228 perf record -p 228 -g # 生成perf.data, Ctrl + C結束錄制 perf report # 可正常讀取
生成火焰圖
perf script -i perf.data &> perf.unfold # 捕獲堆棧 ./FlameGraph/FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded # 折疊堆棧 ./FlameGraph/FlameGraph/flamegraph.pl perf.folded > perf.svg # 生成火焰圖
瀏覽器打開.svg圖片
ros2的CPU占用,播包5min
ros1的CPU占用,播包5min
對比結論:
- 節(jié)點總體CPU占用在102%
- 長時播包測試可知,節(jié)點的CPU占用主要來自std::thread::State_impl占74.51%,其中主程序25%+多線程相關45%
- 多線程相關的45%分析
- 對比ros1的CPU占用,在ros2中節(jié)點的CPU占用高只是運行機制的差異
- 對多線程管理占用的45%的CPU,包含除主程序外的多個任務:不同topic消息隊列同步訪問,消息轉proto,消息收發(fā)同步;線程同步統(tǒng)計節(jié)點掉線信息;線程同步維護節(jié)點狀態(tài)信息等
- 此外,在添加多線程同步前,這部分的CPU還是1-2核占滿,線程間阻塞同步的方式降低了一個核以上的CPU占用,但線程同步還存在一部分的CPU占用
以上就是Linux使用perf分析CPU占用情況的方法步驟的詳細內容,更多關于Linux perf分析CPU的資料請關注腳本之家其它相關文章!
相關文章
Ubuntu徹底卸載MySQL、Apache2和Php的方法教程
這篇文章主要給大家介紹了關于在Ubuntu系統(tǒng)下徹底卸載MySQL、Apache2和Php的方法教程,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面跟著小編來一起看看吧。2017-08-08linux下查看內存條數(shù)及每根內存大小的實現(xiàn)方法(推薦)
下面小編就為大家?guī)硪黄猯inux下查看內存條數(shù)及每根內存大小的實現(xiàn)方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-11-11Centos 7.4服務器時間同步配置方法【基于NTP服務】
這篇文章主要介紹了Centos 7.4服務器時間同步配置方法,結合實例形式分析了NTP服務器安裝、啟動、設置時間同步等相關命令及問題解決方法,需要的朋友可以參考下2019-03-03.httacces文件的密碼保護和防止盜鏈的實現(xiàn)方法
盡管有各種各樣的.htaccess用法,但至今最流行的也可能是最有用的做法是將其用于網(wǎng)站目錄可靠的密碼保護。2008-06-06