自編教材分享:第三章—程序性能的分析和測量(三)



本期分享程序性能測量的工具:剖析類工具和監(jiān)視類工具。
函數(shù)剖析工具gprof
Gprof工具是GNU編譯器工具包提供的性能分析工具。使用代碼抽樣和插入技術(shù),收集函數(shù)剖析信息和調(diào)用圖文件,從而給出函數(shù)調(diào)用關(guān)系、調(diào)用次數(shù)、執(zhí)行時(shí)間等信息。此外還會(huì)列出各個(gè)函數(shù)的耗時(shí)比例。
Gprof使用代碼抽樣和插入技術(shù),收集函數(shù)剖析信息和調(diào)用圖文件,從而給出函數(shù)調(diào)用關(guān)系、調(diào)用次數(shù)、執(zhí)行時(shí)間等信息。Gprof是通過在編譯時(shí)插入代碼來分析程序,因此在一些情況下,其給出的結(jié)果會(huì)有不準(zhǔn)確的地方。
Gprof通常和GCC、LLVM等編譯器配合使用,在使用GCC或LLVM編譯鏈接程序時(shí),添加選項(xiàng)-pg,表示產(chǎn)生的程序可以使用gprof分析。程序運(yùn)行結(jié)束后,會(huì)在程序退出的路徑下生成一個(gè)gmon.out文件。gmo.out文件是記錄并保存下來的監(jiān)控?cái)?shù)據(jù),可以通過命令行方式操作或圖形化工具Kprof來解讀這些數(shù)據(jù)并對(duì)程序的性能進(jìn)行分析,便可得到優(yōu)化人員可閱讀的信息。

Gprof輸出結(jié)果主要包含兩部分,剖析文件Flat profile和調(diào)用圖Call graph。
Flat profile中每一行代表一個(gè)函數(shù),各列參數(shù)含義為,%time:函數(shù)獨(dú)立運(yùn)行時(shí)間,不包含被該函數(shù)調(diào)用的其它函數(shù)的運(yùn)行時(shí)間,占總運(yùn)行時(shí)間的百分比; Cumulative seconds: 所有函數(shù)的累積運(yùn)行時(shí)間,包括自身; Self seconds: 函數(shù)的獨(dú)立運(yùn)行時(shí)間,單位為秒; Calls:函數(shù)被調(diào)用的次數(shù); Selfs/call: 函數(shù)每次調(diào)用的平均獨(dú)立運(yùn)行時(shí)間,單位為秒; Totals/call: 函數(shù)每次調(diào)用的平均整體運(yùn)行時(shí)間,包括被它調(diào)用的其它函數(shù)的運(yùn)行時(shí)間,單位為秒。

調(diào)用圖的每一部分代表一個(gè)函數(shù),最左邊顯示了該函數(shù)的運(yùn)行索引。位于該索引之上的是調(diào)用當(dāng)前函數(shù)的函數(shù),之下的是被當(dāng)前函數(shù)調(diào)用的函數(shù)。%time對(duì)應(yīng)函數(shù)運(yùn)行時(shí)間,包括被調(diào)用函數(shù)的運(yùn)行時(shí)間,占總運(yùn)行時(shí)間的百分比。Self對(duì)應(yīng)函數(shù)的獨(dú)立運(yùn)行時(shí)間,Children對(duì)應(yīng)函數(shù)的整體運(yùn)行時(shí)間減去獨(dú)立運(yùn)行時(shí)間,Called對(duì)應(yīng)函數(shù)的調(diào)用次數(shù)。

可視化軟件性能分析工具oneAPI
Intel推出的oneAPI 2022工具是基于 Intel oneAPI 這一編程模型開發(fā)的產(chǎn)品之一,包含編譯器、函數(shù)庫、預(yù)先優(yōu)化框架以及先進(jìn)的分析調(diào)試工具等組件。Intel oneAPI toolkits中的VTune是一個(gè)用于分析和優(yōu)化程序性能的工具,可以通過從系統(tǒng)中收集性能數(shù)據(jù)、從系統(tǒng)到源代碼不同的層次以及形式上組織和展示數(shù)據(jù)、發(fā)現(xiàn)潛在的性能問題并提出改進(jìn)措施這三個(gè)方面,幫助優(yōu)化人員找到性能不理想的原因并針對(duì)性的對(duì)程序進(jìn)行優(yōu)化。

Intel?Advisor由一組工具或視角組成,Intel Advisor能夠從向量化、CPU/GPU /內(nèi)存性能上限、卸載建模以及線程角度分析代碼,可以幫助優(yōu)化人員分析程序中影響大、優(yōu)化不足的循環(huán)優(yōu)化瓶頸,還可以根據(jù)硬件施加的性能上限可視化實(shí)際性能,給出下一步的優(yōu)化步驟建議等,從而幫助Fortran、C、C++等多種語言構(gòu)建的應(yīng)用程序達(dá)到較好的性能。

性能分析工具perf
Perf工具是基于用戶空間數(shù)據(jù)上的命令行性能分析工具,支持軟硬件計(jì)數(shù)器,并可以像strace工具一樣跟蹤內(nèi)核調(diào)用。借助perf工具,應(yīng)用程序可以使用性能監(jiān)控單元(performance monitoring unit,PMU)、tracepoint和內(nèi)核中的特殊計(jì)數(shù)器來進(jìn)行性能統(tǒng)計(jì)。
在進(jìn)行Perf輸出結(jié)果分析時(shí)首先要找到程序中最耗時(shí)的代碼片段即程序熱點(diǎn),再判斷是否能夠提升熱點(diǎn)代碼的執(zhí)行效率。參數(shù)含義為,Task-clock-msecs:CPU利用率,若該值較高則說明程序的多數(shù)時(shí)間花費(fèi)在CPU計(jì)算上而非 IO;Context-switches:進(jìn)程切換次數(shù),記錄了程序運(yùn)行過程中發(fā)生了多少次進(jìn)程切換,頻繁的進(jìn)程切換是需要避免的。

CUDA程序性能分析工具nvprof
Nvprof工具是NVIDIA開發(fā)的用于分析CUDA程序性能的工具,可以統(tǒng)計(jì)各個(gè)內(nèi)核和CUDA函數(shù)的運(yùn)行效率,還可以給出硬件計(jì)數(shù)器的值。和CUDA函數(shù)的運(yùn)行效率,還可以給出硬件計(jì)數(shù)器的值。比如某個(gè)計(jì)算單元上一共發(fā)出了多少指令,核心一共發(fā)射和執(zhí)行了多少條指令等。
使用nvprof非常簡單,通常只需要在CUDA程序前面加上nvprof。例:

監(jiān)視類工具
系統(tǒng)活動(dòng)情況報(bào)告工具sar
Sar工具是Linux系統(tǒng)上最為全面的系統(tǒng)性能測量工具之一,可以從多方面對(duì)系統(tǒng)的活動(dòng)進(jìn)行報(bào)告,包括文件的讀寫情況、系統(tǒng)調(diào)用的使用情況、磁盤I/O、CPU效率、內(nèi)存利用率、進(jìn)程活動(dòng)及網(wǎng)絡(luò)流量等。
Sar命令常用格式及使用方法為:
簡單示例:
這個(gè)命令表示每間隔1秒鐘統(tǒng)計(jì)一次,總共統(tǒng)計(jì)三次。參數(shù)含義為,%user用戶空間的CPU使用;%nice改變過優(yōu)先級(jí)的進(jìn)程的CPU使用率;%system內(nèi)核空間的CPU使用率;%iowaitCPU等待IO的百分比;%steal管理程序維護(hù)另一個(gè)虛擬處理器時(shí),虛擬CPU的無意識(shí)等待時(shí)間百分比。

要判斷系統(tǒng)瓶頸問題,有時(shí)需要幾個(gè)sar命令選項(xiàng)結(jié)合起來。
如果懷疑CPU存在瓶頸,可用sar -u和sar -q等來查看。
如果懷疑內(nèi)存存在瓶頸,可用sar -B、sar -r和sar -W等來查看。
如果懷疑I/O存在瓶頸,可用sar -b、sar -u和sar -d等來查看。
指標(biāo)性能分析技巧:
若%iowait的值過高,表示硬盤存在I/O瓶頸;
若%idle 的值高但系統(tǒng)響應(yīng)慢時(shí),有可能是CPU等待分配內(nèi)存,此時(shí)應(yīng)加大內(nèi)存容量;
若%idle 的值持續(xù)低于1,則系統(tǒng)的 CPU 處理能力相對(duì)較低,表明系統(tǒng)中最需要解決的資源是CPU。
監(jiān)控網(wǎng)絡(luò)工具netstat
Netstat工具是一個(gè)監(jiān)控TCP/IP網(wǎng)絡(luò)的非常有用的工具,它可以顯示路由表、實(shí)際的網(wǎng)絡(luò)連接以及每一個(gè)網(wǎng)絡(luò)接口設(shè)備的狀態(tài)信息,也可以顯示與IP、TCP、UDP和ICMP協(xié)議相關(guān)的統(tǒng)計(jì)數(shù)據(jù),一般用于查詢本機(jī)各端口的網(wǎng)絡(luò)連接情況。
Netstat命令常用格式及使用方法為:
使用netstat命令時(shí),系統(tǒng)會(huì)把性能統(tǒng)計(jì)信息以概要形式呈現(xiàn),路由信息等以快照形式呈現(xiàn)。參數(shù)含義為,Protoco:協(xié)議的簡稱,可以是 TCP 或 UDP; Recv-Q:接收隊(duì)列,數(shù)字一般都應(yīng)該是0,如果不是,則表示軟件包正在隊(duì)列中堆積; Send-Q:發(fā)送隊(duì)列;Local Address:本機(jī)的 IP 和端口號(hào); Foreign Address:所要連接的主機(jī)名稱和服務(wù);State:指現(xiàn)在連接的狀態(tài),LISTEN 等待接收連接, ESTABLISHED 一個(gè)處于活躍狀態(tài)的連接;TIME_WAIT 一個(gè)剛被終止的連接,它只持續(xù)1至2分鐘,然后就會(huì)變成 LISTEN 狀態(tài)。

監(jiān)控硬盤工具iotop
Iotop用來監(jiān)控硬盤 I/O的使用情況,其界面和top類似,包括 PID、用戶、IO、進(jìn)程等相關(guān)信息。Linux下系統(tǒng)自帶的I/O統(tǒng)計(jì)工具如iostat等大多數(shù)是只能統(tǒng)計(jì)到單碟設(shè)備的讀寫情況,如果想知道每個(gè)進(jìn)程是如何使用I/O的就比較麻煩,使用iotop命令可以很方便的查看,命令iotop -h可以查看使用幫助,最簡單的方法就是直接使用iotop命令。
通過輸出結(jié)果,可以清楚地知道磁盤 I/O 的使用狀況。其中,Total DISK READ與Total DISK WRITE一方面表示了進(jìn)程和內(nèi)核線程之間總的讀寫帶寬,另一方面也表示內(nèi)核塊設(shè)備子系統(tǒng)的情況;Actual DISK READ與Actual DISK WRITE表示在內(nèi)核塊設(shè)備子系統(tǒng)和硬件對(duì)應(yīng)的實(shí)際磁盤I/O帶寬;TID表示線程號(hào)或進(jìn)程號(hào);PRIO表示線程運(yùn)行時(shí)的I/O優(yōu)先級(jí);USER表示進(jìn)程所屬用戶;DISK READ表示刷新時(shí)間間隔內(nèi)讀取數(shù)據(jù)量;DISK WRITE表示刷新時(shí)間間隔內(nèi)寫入數(shù)據(jù)量;SWAPIN表示每個(gè)進(jìn)程的交換使用率;IO表示每個(gè)進(jìn)程的 I/O 利用率,包含磁盤和交換;COMMAND表示進(jìn)程名。

實(shí)時(shí)系統(tǒng)監(jiān)控工具mpstat
Mpstat是實(shí)時(shí)系統(tǒng)監(jiān)控工具,用于報(bào)告CPU相關(guān)的一些統(tǒng)計(jì)信息,這些信息存放在/proc/stat文件中。在多CPU系統(tǒng)中,其不但能查看所有CPU的平均狀態(tài)信息,而且能夠查看特定CPU的信息。例如命令表示每2秒對(duì)所有處理器統(tǒng)計(jì)數(shù)據(jù)報(bào)告,采集三次信息并輸出。

