系統(tǒng)級性能優(yōu)化通常包括兩個階段:性能剖析(performance profiling)和代碼優(yōu)化。
性能剖析的目標是尋找性能瓶頸,查找引發(fā)性能問題的原因及熱點代碼。
代碼優(yōu)化的目標是針對具體性能問題而優(yōu)化代碼或編譯選項,以改善軟件性能。
在性能剖析階段,需要借助于現(xiàn)有的profiling工具,如perf等。在代碼優(yōu)化階段往往需要借助開發(fā)者的經驗,編寫簡潔高效的代碼,甚至在匯編級別合理使用各種指令,合理安排各種指令的執(zhí)行順序。
perf是一款Linux性能分析工具。Linux性能計數器是一個新的基于內核的子系統(tǒng),它提供一個性能分析框架,比如硬件(CPU、PMU(Performance Monitoring Unit))功能和軟件(軟件計數器、tracepoint)功能。
通過perf,應用程序可以利用PMU、tracepoint和內核中的計數器來進行性能統(tǒng)計。它不但可以分析制定應用程序的性能問題(per thread),也可以用來分析內核的性能問題,當然也可以同事分析應用程序和內核,從而全面理解應用程序中的性能瓶頸。
使用perf,可以分析程序運行期間發(fā)生的硬件事件,比如instructions retired、processor clock cycles等;也可以分析軟件時間,比如page fault和進程切換。
perf是一款綜合性分析工具,大到系統(tǒng)全局性性能,再小到進程線程級別,甚至到函數及匯編級別。
perf工具
tar -xvf perf-5.9.0.tar.gz
cd perf-5.9.0
cd tools/perf/
make
sudo cp perf /usr/local/bin
其中安裝會出現(xiàn)以下問題:
2.安裝flexWarning: Kernel ABI header at 'tools/include/uapi/drm/i915_drm.h' differs from latest version at 'include/uapi/drm/i915_drm.h'
Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h'
Warning: Kernel ABI header at 'tools/include/uapi/linux/prctl.h' differs from latest version at 'include/uapi/linux/prctl.h'
Warning: Kernel ABI header at 'tools/arch/x86/include/asm/disabled-features.h' differs from latest version at 'arch/x86/include/asm/disabled-features.h'
Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h'
Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/kvm.h' differs from latest version at 'arch/x86/include/uapi/asm/kvm.h'
Warning: Kernel ABI header at 'tools/arch/powerpc/include/uapi/asm/kvm.h' differs from latest version at 'arch/powerpc/include/uapi/asm/kvm.h'
Warning: Kernel ABI header at 'tools/arch/s390/include/uapi/asm/kvm.h' differs from latest version at 'arch/s390/include/uapi/asm/kvm.h'
Makefile.config:137: *** Error: flex is missing on this system, please install it. Stop.
Makefile.perf:203: recipe for target 'sub-make' failed
make[1]: *** [sub-make] Error 2
Makefile:69: recipe for target 'all' failed
make: *** [all] Error 2
flex如果不安裝,后面在編譯的時候,會出現(xiàn)信賴報錯。
flex安裝命令:
yum install flex -y
3.安裝bisonbison如果沒有安裝,會報以下錯誤。
BUILD: Doing 'make -j4' parallel build
Warning: Kernel ABI header at 'tools/include/uapi/drm/i915_drm.h' differs from latest version at 'include/uapi/drm/i915_drm.h'
Warning: Kernel ABI header at 'tools/include/uapi/linux/kvm.h' differs from latest version at 'include/uapi/linux/kvm.h'
Warning: Kernel ABI header at 'tools/include/uapi/linux/prctl.h' differs from latest version at 'include/uapi/linux/prctl.h'
Warning: Kernel ABI header at 'tools/arch/x86/include/asm/disabled-features.h' differs from latest version at 'arch/x86/include/asm/disabled-features.h'
Warning: Kernel ABI header at 'tools/arch/x86/include/asm/cpufeatures.h' differs from latest version at 'arch/x86/include/asm/cpufeatures.h'
Warning: Kernel ABI header at 'tools/arch/x86/include/uapi/asm/kvm.h' differs from latest version at 'arch/x86/include/uapi/asm/kvm.h'
Warning: Kernel ABI header at 'tools/arch/powerpc/include/uapi/asm/kvm.h' differs from latest version at 'arch/powerpc/include/uapi/asm/kvm.h'
Warning: Kernel ABI header at 'tools/arch/s390/include/uapi/asm/kvm.h' differs from latest version at 'arch/s390/include/uapi/asm/kvm.h'
Makefile.config:141: *** Error: bison is missing on this system, please install it. Stop.
Makefile.perf:203: recipe for target 'sub-make' failed
make[1]: *** [sub-make] Error 2
Makefile:69: recipe for target 'all' failed
make: *** [all] Error 2
安裝命令:
yum install bison -y
二、設置環(huán)境變量永久生效我們普通用戶一般在 ~/.bashrc 或者 ~/.bash_profile 添加就可以了,不要往 /etc/bashrc 里添加。注意:以 . 開頭的文件時隱藏文件。
MobaXterm實現(xiàn)linux和windows之間傳輸文件的具體步驟,以下就是具體的操作教程:
下載軟件路徑:
MobaXterm
可以選擇免安裝版(我已經試過非常好用,免費哦?。?br />
注意:我測試的centos服務器是在某某云上購買的遠程服務器。不是虛擬機。
打開MobaXterm客戶端。
點擊session列表,或者直接點擊“Start local terminal”。然后輸入:ssh root@ -p。
@前面是登錄用戶名,@后面是ip地址。-p后面跟地是密碼。
彈出來提示,輸入密碼,確認后登錄linux服務。在左側可以看到服務器的文件列表。
在地址欄輸入,要上傳到的目錄位置。例如:上傳到/root/.config/下面。在地址欄的位置輸入:/root/.config/,點擊回車跳轉到該目錄下。
如圖,點擊上傳按鈕?;蛴益I選擇“upload to current folder”。
在服務器點擊選擇要下載的文件或目錄。點擊下載按鈕,或右鍵點擊文件/目錄,選擇“download”。
trace的跟蹤方法是一種總體跟蹤法,換句話說,你統(tǒng)計了一個事件到下一個事件所有的時間長度,然后把它們放到時間軸上,你可以知道整個系統(tǒng)運行在時間軸上的分布。
這種方法很準確,但跟蹤成本很高。所以,我們也需要一種抽樣形態(tài)的跟蹤方法。perf提供的就是這樣的跟蹤方法。
perf的原理是這樣的:每隔一個固定的時間,就在CPU上(每個核上都有)產生一個中斷,在中斷上看看,當前是哪個pid,哪個函數,然后給對應的pid和函數加一個統(tǒng)計值,這樣,我們就知道CPU有百分幾的時間在某個pid,或者某個函數上了。這個原理圖示如下:
很明顯可以看出,這是一種采樣的模式,我們預期,運行時間越多的函數,被時鐘中斷擊中的機會越大,從而推測,那個函數(或者pid等)的CPU占用率就越高。
當然,如果某個進程運氣特別好,它每次都剛好躲過你發(fā)起探測的位置,你的統(tǒng)計結果可能就完全是錯的了。這是所有采樣統(tǒng)計都有可能遇到的問題了。
1.perf的使用perf --help之后可以看到perf的二級命令。
全局性概況:
perf list查看當前系統(tǒng)支持的性能事件;
perf bench對系統(tǒng)性能進行摸底;
perf test對系統(tǒng)進行健全性測試;
perf stat對全局性能進行統(tǒng)計;
全局細節(jié):
perf top可以實時查看當前系統(tǒng)進程函數占用率情況;
perf probe可以自定義動態(tài)事件;
特定功能分析:
perf kmem針對slab子系統(tǒng)性能分析;
perf kvm針對kvm虛擬化分析;
perf lock分析鎖性能;
perf mem分析內存slab性能;
perf sched分析內核調度器性能;
perf trace記錄系統(tǒng)調用軌跡;
最常用功能perf record,可以系統(tǒng)全局,也可以具體到某個進程,更甚具體到某一進程某一事件;可宏觀,也可以很微觀:
pref record記錄信息到perf.data;
perf report生成報告;
perf diff對兩個記錄進行diff;
perf evlist列出記錄的性能事件;
perf annotate顯示perf.data函數代碼;
perf archive將相關符號打包,方便在其它機器進行分析;
perf script將perf.data輸出可讀性文本;
可視化工具perf timechart:
2.perf簡單介紹perf timechart record記錄事件;
perf timechart生成output.svg文檔;
執(zhí)行perf --help命令我們可以看到其支持的一堆子命令:
我們可以看到其中很多命令都是非常常用的,比如record(report/script),top,stat等等,尤其是top,甚至可以看到匯編級別的熱代碼,是十分牛逼的一個分析工具。這些子命令也分別擁有自己的help命令??梢钥吹絧erf本身提供的文檔并不多,更詳細的文檔在源碼的tools/perf/Documentation中。
perf本身的原理也非常有意思,其把事件源視為perf_event,并分為task和CPU兩個維度進行事件觸發(fā),本身支持counting,sampling以及bpf作為事件的處理流程。事件源類型(不是機制)被分為Hardware Events,Software Events,Tracepoint,USDT以及Timed Profiling。
bpfTrace內部也是可以基于perf_event機制去做事件源的:
這篇文章先枚舉幾個基本但使用方法,然后分別介紹不同的事件類型與簡單原理,最后進行總結。
這一章節(jié)主要是列舉一些常用的perf子命令,這些都可以應用到我們平時的排錯過程中。
我們介紹幾個比較有意思的perf命令,并簡單實操下這幾個命令,感受下這個神器的威力。
首先執(zhí)行sudo perf list ‘:’ | less,查看所有支持的Tracepoint Event。
1.perf list然后可以執(zhí)行sudo perf record -e ‘sched:sched_switch’ -ag:
這個命令對sched:sched_switch進行檢測,并對數據進行聚合,-a對意思是對所有CPU都進行數據采集,-g對意思收集棧幀對消息,最后把數據輸出到perf.data文件中。
然后執(zhí)行sudo perf report,即可以查看perf.data文件,因為我們加了-g,所以可以看到每一項數據的棧幀。
2.perf top首先我們可以隨意啟動一個進程,這里我啟動一個redis實例,找到其進程號然后執(zhí)行sudo perf top -p 23981 -F 300HZ,這個指令的意思是300HZ就執(zhí)行一個CPU-lock事件,查找進程23981的調用信息。然后我們就可以看到一個調用頻率的排行,用方向鍵和回車可以查看一個事件的詳細信息,甚至可以看到匯編級別的熱代碼。
最經典的計數命令當然也不能少,我們可以執(zhí)行如下命令sudo perf stat -e ‘sched:*’ -p 23981 sleep 10,可以查看被監(jiān)控事件的counter數據。
好了,現(xiàn)在我們用的一直都是pre-defined的事件,現(xiàn)在我們來嘗試動態(tài)加入一個Tracepoint,執(zhí)行如下命令sudo perf probe --add udp_sendmsg,這樣我們就在udp_sendmsg中埋上了點:
我們可以執(zhí)行如下指令查看對于指定probe來說有效的局部變量perf probe -V udp_sendmsg:
我們可以檢測某個局部變量sudo perf probe --add ‘udp_sendmsg len’ -f,因為前面有同名的probe,需要加-f。然后執(zhí)行sudo perf record -e probe:udp_sendmsg_1 -a采集數據,最后執(zhí)行sudo perf report,可以看到len的值。我遇到的問題是report中的值都是十六進制數,也就是調試信息沒有找到。
在內核的代碼中查看Makefile,可以看到在定義了CONFIG_FRAME_POINTER和CONFIG_DEBUG_INFO時才會加載調試信息:
既然沒有,說明編譯內核的時候沒有對應的調試信息,而且/proc/kallsyms文件大小也為零。
那理論我們使用kernel-debuginfo包就可以解決問題。yum下載以后可以執(zhí)行sudo find / -name "kernel-debuginfo"找到包的下載路徑,然后執(zhí)行record --vmlinux=path,然后發(fā)現(xiàn)好像不是這么用的,找到[15]修改了vmlinux的參數為/boot下的文件,發(fā)現(xiàn)還是沒有辦法解決問題。
奇了大怪,到底該怎么找到調試符號呢,可能重新編譯內核,加上調試信息就可以吧(但其他但perf信息就可以看到內核但堆棧信息,所以應該是操作問題)。事實上到現(xiàn)在我還是沒有解決這個問題。
5.perf lock我們可以檢測鎖的各種信息,但是需要CONFIG_LOCKDEP和CONFIG_LOCK_STAT編譯選項的開啟,執(zhí)行如下指令perf lock record ls,然后執(zhí)行perf lock report,就可以看到詳細的信息。相比之SystemTap/bpfTrace就什么也不需要,直接就可以采集到perf可以采集到的所有數據,但是需要腳本編寫者自身對內核代碼有所了解。
我的機器編譯時沒有開這個:
我們可以檢測內核中的內存分配情況,首先執(zhí)行sudo perf kmem record ls,然后執(zhí)行sudo perf kmem stat --caller --alloc,就可以看到內核中內存分配的信息了:
我們也可以查看調度相關的事件,執(zhí)行如下命令sudo perf sched record -p 23981,然后執(zhí)行sudo perf report latency就可以查看一些調度屬性。
因為是調度相關,先給redis benchmark上,執(zhí)行./redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 1000000,然后執(zhí)行第一個命令,一兩秒就累計了600MB的數據,然后執(zhí)行第二個命令,我們可以看到如下輸出:
然后調用sudo perf sched script,我們就可以知道這個最高的時延發(fā)生的原因是什么:
還有一個子命令非常有意思,就是sudo perf sched map,這可以用圖表的方式來查看不同CPU核上任務的轉移情況,這種情況下顯然前面監(jiān)控redis的perf.data就不太適合作為例子了,因為絕大多數情況redis實例都是在一個核上跑的,我們先執(zhí)行:sudo perf sched record – sleep 1,再執(zhí)行sudo perf sched map,可以看到類似這樣的輸出:
其中類似A0,B0,C0這樣的標識符代表了一個任務,然后*代表CPU剛剛調度一個事件,.代表此CPU目前空閑,這種分析可以很好的觀測當前系統(tǒng)中任務切換的情況。但是我認為能解決的問題有限,還是latecny搭配script實用一點。
奇怪的一個子命令,這個命令可以看到所監(jiān)控事件部分的高級語言代碼和匯編,但是打印出來好像也沒啥用,我發(fā)現(xiàn)不管去觀察哪一個pref.data,總會有一句匯編是百分百的命中率,如果能夠看到這個命令每句指令的命中情況的話就很棒了:
你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧