自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux內(nèi)核追蹤神器:perf實(shí)現(xiàn)原理剖析

系統(tǒng) Linux
在 Linux 性能分析的廣袤領(lǐng)域中,Perf 猶如一顆璀璨的明星,散發(fā)著獨(dú)特的光芒。Perf,即 Performance 的縮寫,是一款集成于 Linux 內(nèi)核的性能分析工具,如同一位技藝精湛的診斷大師,能深入系統(tǒng)的各個(gè)角落,精準(zhǔn)地剖析系統(tǒng)性能。

在 Linux 內(nèi)核的廣袤天地里,性能優(yōu)化與故障排查宛如兩座高聳的山峰,橫亙?cè)陂_(kāi)發(fā)者前行的道路上。為了攀登這兩座高峰,開(kāi)發(fā)者們不斷尋覓著強(qiáng)大的工具。而 perf,無(wú)疑是其中最為耀眼的 “神器” 之一。當(dāng)你在運(yùn)行一個(gè)復(fù)雜的 Linux 系統(tǒng)時(shí),是否常常被一些莫名的性能問(wèn)題所困擾?系統(tǒng)突然變得卡頓,應(yīng)用程序響應(yīng)遲緩,可你卻無(wú)從下手,不知問(wèn)題究竟出在哪里?;蛟S是某個(gè)內(nèi)核函數(shù)在不經(jīng)意間消耗了大量資源,又或許是進(jìn)程間的資源競(jìng)爭(zhēng)引發(fā)了瓶頸。

在過(guò)去,面對(duì)這些問(wèn)題,開(kāi)發(fā)者們猶如在黑暗中摸索,只能憑借經(jīng)驗(yàn)和猜測(cè)來(lái)進(jìn)行調(diào)試。但 perf 的出現(xiàn),徹底改變了這一局面。它就像一把精準(zhǔn)的手術(shù)刀,能夠深入到內(nèi)核的每一個(gè)角落,精準(zhǔn)地剖析系統(tǒng)性能。從處理器的指令周期,到緩存的命中率;從函數(shù)的調(diào)用頻率,到進(jìn)程的上下文切換,perf 都能提供詳盡的數(shù)據(jù)。接下來(lái),讓我們一同深入 perf 的世界,探尋它究竟是如何實(shí)現(xiàn)這一強(qiáng)大功能的,看看它是怎樣在復(fù)雜的內(nèi)核環(huán)境中,為我們揭示性能奧秘,助力解決棘手的問(wèn)題 。

一、Perf工具簡(jiǎn)介

1.1什么是 Perf

在 Linux 性能分析的廣袤領(lǐng)域中,Perf 猶如一顆璀璨的明星,散發(fā)著獨(dú)特的光芒。Perf,即 Performance 的縮寫,是一款集成于 Linux 內(nèi)核的性能分析工具,如同一位技藝精湛的診斷大師,能深入系統(tǒng)的各個(gè)角落,精準(zhǔn)地剖析系統(tǒng)性能。它以事件驅(qū)動(dòng)為核心機(jī)制,如同精密的儀器,能夠捕捉到硬件、軟件以及內(nèi)核層面的各種性能事件。

隨著 Linux 內(nèi)核的不斷演進(jìn),Perf 也在持續(xù)發(fā)展壯大。從最初簡(jiǎn)單的性能監(jiān)測(cè),到如今具備豐富多樣的功能,Perf 已經(jīng)成為 Linux 性能分析不可或缺的工具。它不僅支持硬件事件的監(jiān)測(cè),如 CPU 時(shí)鐘周期、緩存命中情況等,這些硬件事件猶如系統(tǒng)運(yùn)行的脈搏,反映著硬件的工作狀態(tài);還能捕捉軟件事件,如進(jìn)程切換、缺頁(yè)中斷等,這些軟件事件則是系統(tǒng)運(yùn)行的 “軟指標(biāo)”,揭示著軟件層面的運(yùn)行效率。此外,內(nèi)核追蹤點(diǎn)事件、用戶程序靜態(tài)追蹤點(diǎn)以及動(dòng)態(tài)追蹤等功能,更是讓 Perf 的監(jiān)測(cè)能力如虎添翼,能夠全方位、深層次地洞察系統(tǒng)性能。

1.2Perf 的強(qiáng)大功能

Perf 之所以備受贊譽(yù),是因?yàn)樗鼡碛幸幌盗袕?qiáng)大而實(shí)用的功能,這些功能猶如一把把精準(zhǔn)的手術(shù)刀,能夠深入剖析系統(tǒng)性能的各個(gè)方面。Perf是內(nèi)置于Linux內(nèi)核源碼樹(shù)中的性能剖析(profiling)工具。它基于事件采樣原理,以性能事件為基礎(chǔ),支持針對(duì)處理器相關(guān)性能指標(biāo)與操作系統(tǒng)相關(guān)性能指標(biāo)的性能剖析,常用于性能瓶頸的查找與熱點(diǎn)代碼的定位。

(1)輕量級(jí)事件采樣

Perf 具備輕量級(jí)事件采樣的能力,這使其能夠通過(guò)硬件性能計(jì)數(shù)對(duì)處理器事件進(jìn)行采樣,從而獲取應(yīng)用程序或內(nèi)核的性能數(shù)據(jù) 。它可以監(jiān)測(cè)指令執(zhí)行的數(shù)量,了解程序在運(yùn)行過(guò)程中到底執(zhí)行了多少條指令,這就像是記錄一場(chǎng)比賽中運(yùn)動(dòng)員的動(dòng)作次數(shù),能直觀反映出程序的工作量。緩存命中率也是它的監(jiān)測(cè)范圍,緩存作為計(jì)算機(jī)系統(tǒng)中速度較快的存儲(chǔ)區(qū)域,緩存命中率的高低直接影響著系統(tǒng)的性能,Perf 能夠精確地捕捉到緩存命中的次數(shù)以及未命中的次數(shù),讓我們清楚地知道緩存的工作效率。分支預(yù)測(cè)同樣逃不過(guò) Perf 的 “眼睛”,分支預(yù)測(cè)是處理器為了提高執(zhí)行效率而采用的一種技術(shù),Perf 可以監(jiān)測(cè)分支預(yù)測(cè)的成功率,幫助我們?cè)u(píng)估處理器在這方面的性能表現(xiàn)。這些監(jiān)測(cè)指標(biāo)就像一個(gè)個(gè)關(guān)鍵的信號(hào),為我們揭示了系統(tǒng)性能的奧秘。

(2)Trace 功能

Trace 功能是 Perf 的又一強(qiáng)大武器,它可以跟蹤進(jìn)程或內(nèi)核的函數(shù)調(diào)用鏈,如同一位經(jīng)驗(yàn)豐富的偵探,能夠順著線索找出代碼的執(zhí)行路徑。通過(guò)這一功能,Perf 可以生成函數(shù)調(diào)用圖,函數(shù)調(diào)用圖就像是一幅詳細(xì)的地圖,展示了各個(gè)函數(shù)之間的調(diào)用關(guān)系,讓我們一目了然地看到程序的執(zhí)行流程?;鹧鎴D也是 Perf Trace 功能的重要產(chǎn)物,火焰圖以一種直觀的方式展示了函數(shù)的執(zhí)行時(shí)間和調(diào)用棧深度,越寬的部分表示該函數(shù)占用的時(shí)間越長(zhǎng),就像火焰的大小反映了火勢(shì)的強(qiáng)弱,幫助我們快速定位性能瓶頸所在。在一個(gè)復(fù)雜的應(yīng)用程序中,可能存在多個(gè)函數(shù)相互調(diào)用,通過(guò)火焰圖,我們可以輕松地發(fā)現(xiàn)哪些函數(shù)占用了大量的時(shí)間,從而有針對(duì)性地進(jìn)行優(yōu)化。

(3)Profiling 功能

Profiling 功能使 Perf 能夠?qū)μ囟ǖ膽?yīng)用程序進(jìn)行深入分析,找出其中最耗時(shí)的函數(shù)和代碼行。它提供了逐行統(tǒng)計(jì)的功能,就像一位細(xì)心的校對(duì)員,對(duì)每一行代碼的執(zhí)行時(shí)間進(jìn)行統(tǒng)計(jì),讓我們清楚地知道每一行代碼對(duì)性能的影響?;鹧鎴D在 Profiling 功能中同樣發(fā)揮著重要作用,通過(guò)火焰圖,我們可以從宏觀的角度看到整個(gè)程序的性能熱點(diǎn),快速鎖定需要優(yōu)化的區(qū)域。熱點(diǎn)分析也是 Perf Profiling 功能的重要組成部分,它能夠幫助我們找出程序中最常被訪問(wèn)或執(zhí)行時(shí)間最長(zhǎng)的代碼區(qū)域,這些區(qū)域往往是性能優(yōu)化的關(guān)鍵所在。在開(kāi)發(fā)一個(gè)大型軟件項(xiàng)目時(shí),可能存在一些核心算法或頻繁調(diào)用的函數(shù),通過(guò) Perf 的 Profiling 功能,我們可以準(zhǔn)確地找出這些函數(shù)和代碼行,對(duì)其進(jìn)行優(yōu)化,從而提高整個(gè)軟件的性能。

(4)基準(zhǔn)測(cè)試

在基準(zhǔn)測(cè)試方面,Perf 可以與其他基準(zhǔn)測(cè)試工具如 sysbench、fio 等結(jié)合使用,對(duì)系統(tǒng)的整體性能進(jìn)行全面評(píng)估。與 sysbench 結(jié)合時(shí),Perf 可以測(cè)量 CPU 在不同負(fù)載下的性能表現(xiàn),比如在高并發(fā)的數(shù)據(jù)庫(kù)事務(wù)處理中,CPU 的運(yùn)算速度、響應(yīng)時(shí)間等指標(biāo),這對(duì)于評(píng)估服務(wù)器在實(shí)際業(yè)務(wù)場(chǎng)景中的性能非常重要。在內(nèi)存性能評(píng)估上,Perf 與 fio 配合,能夠精準(zhǔn)地測(cè)量?jī)?nèi)存的讀寫速度、帶寬利用率等參數(shù)。磁盤 IO 性能也是 Perf 的 “拿手好戲”,它可以測(cè)試磁盤的讀寫速率、尋道時(shí)間等關(guān)鍵指標(biāo),為系統(tǒng)調(diào)優(yōu)提供全面而準(zhǔn)確的參考數(shù)據(jù)。在構(gòu)建一個(gè)大型數(shù)據(jù)中心時(shí),需要對(duì)服務(wù)器的性能進(jìn)行全面評(píng)估,Perf 與其他基準(zhǔn)測(cè)試工具的結(jié)合使用,可以幫助我們了解服務(wù)器在不同工作負(fù)載下的性能表現(xiàn),從而合理配置硬件資源,提高系統(tǒng)的整體性能。

(5)調(diào)試功能

Perf 還具備強(qiáng)大的調(diào)試功能,它可以與調(diào)試器如 gdb 結(jié)合使用,為開(kāi)發(fā)人員提供更詳細(xì)的性能分析和調(diào)試信息。在程序運(yùn)行時(shí),Perf 能夠捕獲跟蹤數(shù)據(jù),這些數(shù)據(jù)就像是程序運(yùn)行的 “腳印”,記錄了程序的執(zhí)行過(guò)程。并且,Perf 可以將這些跟蹤數(shù)據(jù)與源代碼進(jìn)行關(guān)聯(lián),就像將案件的線索與嫌疑人的行為聯(lián)系起來(lái),讓開(kāi)發(fā)人員能夠清晰地看到程序在執(zhí)行過(guò)程中各個(gè)函數(shù)的調(diào)用情況、執(zhí)行時(shí)間以及變量的變化等信息,從而更好地理解程序的運(yùn)行機(jī)制,快速定位并解決性能問(wèn)題。在開(kāi)發(fā)一個(gè)復(fù)雜的軟件系統(tǒng)時(shí),可能會(huì)遇到一些難以排查的性能問(wèn)題,通過(guò) Perf 與 gdb 的結(jié)合使用,開(kāi)發(fā)人員可以深入分析程序的執(zhí)行過(guò)程,找出問(wèn)題的根源,提高軟件開(kāi)發(fā)的效率和質(zhì)量。

二、Perf安裝與使用

2.1安裝 Perf

在使用 Perf 之前,首先需要將其安裝到系統(tǒng)中。Perf 在不同的 Linux 發(fā)行版中有不同的安裝方式。

在基于 Debian 或 Ubuntu 的系統(tǒng)中,Perf 工具通常包含在linux-tools-common和linux-tools-<kernel-version>包中。安裝命令如下:

sudo apt-get install linux-tools-common linux-tools-`uname -r`

上述命令中,uname -r用于獲取當(dāng)前系統(tǒng)的內(nèi)核版本,linux-tools-<kernel-version>包會(huì)根據(jù)實(shí)際的內(nèi)核版本進(jìn)行安裝,確保 Perf 與系統(tǒng)內(nèi)核版本兼容。

對(duì)于基于 Red Hat 或 CentOS 的系統(tǒng),可以使用 yum 包管理器進(jìn)行安裝:

sudo yum install perf

如果系統(tǒng)中沒(méi)有配置對(duì)應(yīng)的 yum 源,可能需要先配置 yum 源,再進(jìn)行安裝。yum 源的配置方式根據(jù)不同的系統(tǒng)和需求有所不同,一般可以通過(guò)下載官方的 yum 源配置文件,放置到/etc/yum.repos.d/目錄下,并根據(jù)實(shí)際情況修改文件中的參數(shù),如baseurl、gpgcheck等。

從源碼安裝 Perf 則是另一種安裝方式,適合那些需要定制 Perf 功能或在沒(méi)有包管理器的環(huán)境中安裝的情況。首先,需要從 Linux 內(nèi)核官方網(wǎng)站下載內(nèi)核源碼,下載命令如下:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

下載完成后,進(jìn)入內(nèi)核源碼目錄中的tools/perf子目錄,執(zhí)行make命令進(jìn)行編譯:

cd linux/tools/perf
make

編譯過(guò)程中,系統(tǒng)會(huì)檢查依賴庫(kù)的情況,如果缺少依賴庫(kù),會(huì)提示需要安裝相應(yīng)的庫(kù)。安裝完所有依賴庫(kù)后,再次執(zhí)行make命令進(jìn)行編譯。編譯完成后,在當(dāng)前目錄下會(huì)生成一個(gè)名為perf的二進(jìn)制文件,這就是 Perf 工具。可以將其復(fù)制到系統(tǒng)的可執(zhí)行文件目錄中,如/usr/local/bin/,以便在系統(tǒng)的任何位置都能執(zhí)行 Perf 命令:

sudo cp perf /usr/local/bin/

安裝完成后,可以通過(guò)運(yùn)行perf --version命令來(lái)驗(yàn)證 Perf 是否正確安裝。如果安裝成功,會(huì)顯示 Perf 的版本信息。

2.2Perf的基本使用

CPU周期(cpu-cycles)是默認(rèn)的性能事件,所謂的CPU周期是指CPU所能識(shí)別的最小時(shí)間單元,通常為億分之幾秒,是CPU執(zhí)行最簡(jiǎn)單的指令時(shí)所需要的時(shí)間,例如讀取寄存器中的內(nèi)容,也叫做clock tick。

perf COMMAND [-e event ...] PROGRAM, perf 是采用的這么一個(gè)命令格式, COMMAND一般常用的就是 top, stat, record, report等. 然后用 -e 參數(shù)來(lái)統(tǒng)計(jì)需要關(guān)注的事件. 多個(gè)事件就用多個(gè) -e 連接。

Perf是一個(gè)包含22種子工具的工具集,以下是最常用的5種:

  1. perf-list
  2. perf-stat
  3. perf-top
  4. perf-record
  5. perf-report
  6. perf-trace

⑴perf-list

Perf-list用來(lái)查看perf所支持的性能事件,有軟件的也有硬件的。List all symbolic event types。

perf list [hw | sw | cache | tracepoint | event_glob]

⑵perf stat

說(shuō)明一個(gè)工具的最佳途徑是列舉一個(gè)例子??疾橄旅孢@個(gè)例子程序。其中函數(shù) longa() 是個(gè)很長(zhǎng)的循環(huán),比較浪費(fèi)時(shí)間。函數(shù) foo1 和 foo2 將分別調(diào)用該函數(shù) 10 次,以及 100 次。

//t1.c
 void longa()
 {
   int i,j;
   for(i = 0; i < 1000000; i++)
   j=i; //am I silly or crazy? I feel boring and desperate.
 }

 void foo2()
 {
   int i;
   for(i=0 ; i < 10; i++)
        longa();
 }

 void foo1()
 {
   int i;
   for(i = 0; i< 100; i++)
      longa();
 }

 int main(void)
 {
   foo1();
   foo2();
 }

然后編譯它:

gcc -o t1 -g t1.c

下面演示了 perf stat 針對(duì)程序 t1 的輸出:

root@ubuntu-test:~# perf stat ./t1

 Performance counter stats for './t1':

        218.584169 task-clock # 0.997 CPUs utilized
                18 context-switches # 0.000 M/sec
                 0 CPU-migrations # 0.000 M/sec
                82 page-faults # 0.000 M/sec
       771,180,100 cycles # 3.528 GHz
     <not counted> stalled-cycles-frontend
     <not counted> stalled-cycles-backend
       550,703,114 instructions # 0.71 insns per cycle
       110,117,522 branches # 503.776 M/sec
             5,009 branch-misses # 0.00% of all branches

       0.219155248 seconds time elapsed

程序 t1 是一個(gè) CPU bound 型,因?yàn)?task-clock-msecs 接近 1

對(duì) t1 進(jìn)行調(diào)優(yōu)應(yīng)該要找到熱點(diǎn) ( 即最耗時(shí)的代碼片段 ),再看看是否能夠提高熱點(diǎn)代碼的效率。缺省情況下,除了 task-clock-msecs 之外,perf stat 還給出了其他幾個(gè)最常用的統(tǒng)計(jì)信息:

  • Task-clock-msecs:CPU 利用率,該值高,說(shuō)明程序的多數(shù)時(shí)間花費(fèi)在 CPU 計(jì)算上而非 IO。
  • Context-switches:進(jìn)程切換次數(shù),記錄了程序運(yùn)行過(guò)程中發(fā)生了多少次進(jìn)程切換,頻繁的進(jìn)程切換是應(yīng)該避免的。
  • Cache-misses:程序運(yùn)行過(guò)程中總體的 cache 利用情況,如果該值過(guò)高,說(shuō)明程序的 cache 利用不好
  • CPU-migrations:表示進(jìn)程 t1 運(yùn)行過(guò)程中發(fā)生了多少次 CPU 遷移,即被調(diào)度器從一個(gè) CPU 轉(zhuǎn)移到另外一個(gè) CPU 上運(yùn)行。
  • Cycles:處理器時(shí)鐘,一條機(jī)器指令可能需要多個(gè) cycles,Instructions: 機(jī)器指令數(shù)目。
  • IPC:是 Instructions/Cycles 的比值,該值越大越好,說(shuō)明程序充分利用了處理器的特性。
  • Cache-references: cache 命中的次數(shù),Cache-misses: cache 失效的次數(shù)。

通過(guò)指定 -e 選項(xiàng),您可以改變 perf stat 的缺省事件 ( 關(guān)于事件,在上一小節(jié)已經(jīng)說(shuō)明,可以通過(guò) perf list 來(lái)查看 )。假如您已經(jīng)有很多的調(diào)優(yōu)經(jīng)驗(yàn),可能會(huì)使用 -e 選項(xiàng)來(lái)查看您所感興趣的特殊的事件。

有些程序慢是因?yàn)橛?jì)算量太大,其多數(shù)時(shí)間都應(yīng)該在使用 CPU 進(jìn)行計(jì)算,這叫做 CPU bound 型;有些程序慢是因?yàn)檫^(guò)多的 IO,這種時(shí)候其 CPU 利用率應(yīng)該不高,這叫做 IO bound 型;對(duì)于 CPU bound 程序的調(diào)優(yōu)和 IO bound 的調(diào)優(yōu)是不同的。

⑶perf top

使用 perf stat 的時(shí)候,往往您已經(jīng)有一個(gè)調(diào)優(yōu)的目標(biāo)。比如我剛才寫的那個(gè)無(wú)聊程序 t1。

也有些時(shí)候,您只是發(fā)現(xiàn)系統(tǒng)性能無(wú)端下降,并不清楚究竟哪個(gè)進(jìn)程成為了貪吃的 hog。

此時(shí)需要一個(gè)類似 top 的命令,列出所有值得懷疑的進(jìn)程,從中找到需要進(jìn)一步審查的家伙。

Perf top 用于實(shí)時(shí)顯示當(dāng)前系統(tǒng)的性能統(tǒng)計(jì)信息。該命令主要用來(lái)觀察整個(gè)系統(tǒng)當(dāng)前的狀態(tài),比如可以通過(guò)查看該命令的輸出來(lái)查看當(dāng)前系統(tǒng)最耗時(shí)的內(nèi)核函數(shù)或某個(gè)用戶進(jìn)程。

讓我們?cè)僭O(shè)計(jì)一個(gè)例子來(lái)演示吧,我很快就想到了如代碼清單 2 所示的一個(gè)程序:

//t2.c
main(){
    int i;
    while(1) i++;
}

然后編譯這個(gè)程序:

gcc -o t2 -g t2.c

運(yùn)行這個(gè)程序后, 我們另起一個(gè)窗口,運(yùn)行perf top來(lái)看看:

Events: 8K cycles
 98.67% t2 [.] main
  1.10% [kernel] [k] __do_softirq
  0.07% [kernel] [k] _raw_spin_unlock_irqrestore
  0.05% perf [.] kallsyms__parse
  0.05% libc-2.15.so [.] 0x807c7
  0.05% [kernel] [k] kallsyms_expand_symbol
  0.02% perf [.] map__process_kallsym_symbol

很容易便發(fā)現(xiàn) t2 是需要關(guān)注的可疑程序。不過(guò)其作案手法太簡(jiǎn)單:肆無(wú)忌憚地浪費(fèi)著 CPU。所以我們不用再做什么其他的事情便可以找到問(wèn)題所在。但現(xiàn)實(shí)生活中,影響性能的程序一般都不會(huì)如此愚蠢,所以我們往往還需要使用其他的 perf 工具進(jìn)一步分析。

⑷使用 perf record, 解讀 report

使用 top 和 stat 之后,您可能已經(jīng)大致有數(shù)了。要進(jìn)一步分析,便需要一些粒度更細(xì)的信息。比如說(shuō)您已經(jīng)斷定目標(biāo)程序計(jì)算量較大,也許是因?yàn)橛行┐a寫的不夠精簡(jiǎn)。那么面對(duì)長(zhǎng)長(zhǎng)的代碼文件,究竟哪幾行代碼需要進(jìn)一步修改呢?這便需要使用 perf record 記錄單個(gè)函數(shù)級(jí)別的統(tǒng)計(jì)信息,并使用 perf report 來(lái)顯示統(tǒng)計(jì)結(jié)果。

您的調(diào)優(yōu)應(yīng)該將注意力集中到百分比高的熱點(diǎn)代碼片段上,假如一段代碼只占用整個(gè)程序運(yùn)行時(shí)間的 0.1%,即使您將其優(yōu)化到僅剩一條機(jī)器指令,恐怕也只能將整體的程序性能提高 0.1%。俗話說(shuō),好鋼用在刀刃上,不必我多說(shuō)了。

perf record -e cpu-clock ./t1
perf report

perf report 輸出結(jié)果:

Events: 229 cpu-clock
100.00% t1 t1 [.] longa

不出所料,hot spot 是 longa( ) 函數(shù)。但,代碼是非常復(fù)雜難說(shuō)的,t1 程序中的 foo1() 也是一個(gè)潛在的調(diào)優(yōu)對(duì)象,為什么要調(diào)用 100 次那個(gè)無(wú)聊的 longa() 函數(shù)呢?但我們?cè)谏蠄D中無(wú)法發(fā)現(xiàn) foo1 和 foo2,更無(wú)法了解他們的區(qū)別了。

我曾發(fā)現(xiàn)自己寫的一個(gè)程序居然有近一半的時(shí)間花費(fèi)在 string 類的幾個(gè)方法上,string 是 C++ 標(biāo)準(zhǔn),我絕不可能寫出比 STL 更好的代碼了。因此我只有找到自己程序中過(guò)多使用 string 的地方。因此我很需要按照調(diào)用關(guān)系進(jìn)行顯示的統(tǒng)計(jì)信息。

使用 perf 的 -g 選項(xiàng)便可以得到需要的信息:

perf record -e cpu-clock -g ./t1
perf report

輸出結(jié)果:

Events: 270 cpu-clock
- 100.00% t1 t1 [.] longa
   - longa
      + 91.85% foo1
      + 8.15% foo2

通過(guò)對(duì) calling graph 的分析,能很方便地看到 91.85% 的時(shí)間都花費(fèi)在 foo1() 函數(shù)中,因?yàn)樗{(diào)用了 100 次 longa() 函數(shù),因此假如 longa() 是個(gè)無(wú)法優(yōu)化的函數(shù),那么程序員就應(yīng)該考慮優(yōu)化 foo1,減少對(duì) longa() 的調(diào)用次數(shù)。

⑸使用tracepoint

當(dāng) perf 根據(jù) tick 時(shí)間點(diǎn)進(jìn)行采樣后,人們便能夠得到內(nèi)核代碼中的 hot spot。那什么時(shí)候需要使用 tracepoint 來(lái)采樣呢?

我想人們使用 tracepoint 的基本需求是對(duì)內(nèi)核的運(yùn)行時(shí)行為的關(guān)心,如前所述,有些內(nèi)核開(kāi)發(fā)人員需要專注于特定的子系統(tǒng),比如內(nèi)存管理模塊。這便需要統(tǒng)計(jì)相關(guān)內(nèi)核函數(shù)的運(yùn)行情況。另外,內(nèi)核行為對(duì)應(yīng)用程序性能的影響也是不容忽視的:

以之前的遺憾為例,假如時(shí)光倒流,我想我要做的是統(tǒng)計(jì)該應(yīng)用程序運(yùn)行期間究竟發(fā)生了多少次系統(tǒng)調(diào)用。在哪里發(fā)生的?

下面我用 ls 命令來(lái)演示 sys_enter 這個(gè) tracepoint 的使用:

root@ubuntu-test:~# perf stat -e raw_syscalls:sys_enter ls
bin libexec off perf.data.old t1 t3 tutong.iso
bwtest minicom.log perf.data pktgen t1.c t3.c

 Performance counter stats for 'ls':

               111 raw_syscalls:sys_enter

       0.001557549 seconds time elapsed

個(gè)報(bào)告詳細(xì)說(shuō)明了在 ls 運(yùn)行期間發(fā)生了多少次系統(tǒng)調(diào)用 ( 上例中有 111 次 )。

2.3常用命令詳解

Perf 提供了豐富的命令和參數(shù),以滿足不同的性能分析需求。下面詳細(xì)介紹一些常用的命令及參數(shù)。

(1)列出所有可監(jiān)測(cè)事件

perf list命令用于列出系統(tǒng)中所有可監(jiān)測(cè)的性能事件,這些事件包括硬件性能事件、軟件性能事件以及 tracepoints。硬件性能事件由 CPU 硬件提供,如cycles表示 CPU 時(shí)鐘周期計(jì)數(shù),instructions表示執(zhí)行的指令數(shù),cache-misses表示緩存未命中計(jì)數(shù)等;軟件性能事件由內(nèi)核軟件提供,例如context-switches表示上下文切換的次數(shù),page-faults表示頁(yè)面錯(cuò)誤的次數(shù),cpu-migrations表示 CPU 遷移的次數(shù)等;tracepoints 則是內(nèi)核中靜態(tài) tracepoint 所觸發(fā)的事件,用來(lái)判斷程序運(yùn)行期間內(nèi)核的行為細(xì)節(jié) 。使用perf list命令可以查看系統(tǒng)支持的所有事件類型,例如:

$ perf list
List of pre-defined events (to be used in -e):
  branch-instructions OR branches                    [Hardware event]
  branch-misses                                      [Hardware event]
  bus-cycles                                         [Hardware event]
  cache-misses                                       [Hardware event]
  cache-references                                   [Hardware event]
  cpu-cycles OR cycles                               [Hardware event]
  instructions                                       [Hardware event]
  alignment-faults                                   [Software event]
  bpf-output                                         [Software event]
  context-switches OR cs                             [Software event]
  cpu-clock                                          [Software event]
  cpu-migrations OR migrations                       [Software event]
  dummy                                              [Software event]
  emulation-faults                                   [Software event]
  major-faults                                       [Software event]
  minor-faults                                       [Software event]
  page-faults OR faults                              [Software event]
  task-clock                                         [Software event]
  duration_time                                      [Tool event]
  L1-dcache-load-misses                              [Hardware cache event]
  L1-dcache-loads                                    [Hardware cache event]
  L1-dcache-stores                                   [Hardware cache event]
  L1-icache-load-misses                              [Hardware cache event]
  L1-icache-loads                                    [Hardware cache event]
  branch-load-misses                                 [Hardware cache event]
  branch-loads                                       [Hardware cache event]
  dTLB-load-misses                                   [Hardware cache event]
  dTLB-loads                                         [Hardware cache event]
  dTLB-store-misses                                  [Hardware cache event]
  dTLB-stores                                        [Hardware cache event]
  iTLB-load-misses                                   [Hardware cache event]
  iTLB-loads                                         [Hardware cache event]
  node-load-misses                                   [Hardware cache event]
  node-loads                                         [Hardware cache event]
  node-store-misses                                  [Hardware cache event]
  node-stores                                        [Hardware cache event]
  branch-instructions OR cpu/branch-instructions/    [Kernel PMU event]
  branch-misses OR cpu/branch-misses/                [Kernel PMU event]
  bus-cycles OR cpu/bus-cycles/                      [Kernel PMU event]
  cache-misses OR cpu/cache-misses/                  [Kernel PMU event]
  cache-references OR cpu/cache-references/          [Kernel PMU event]
  cpu-cycles OR cpu/cpu-cycles/                      [Kernel PMU event]
  instructions OR cpu/instructions/                  [Kernel PMU event]
  mem-loads OR cpu/mem-loads/                        [Kernel PMU event]
  mem-stores OR cpu/mem-stores/                      [Kernel PMU event]
  ref-cycles OR cpu/ref-cycles/                      [Kernel PMU event]
  topdown-fetch-bubbles OR cpu/topdown-fetch-bubbles/ [Kernel PMU event]
  topdown-recovery-bubbles OR cpu/topdown-recovery-bubbles/ [Kernel PMU event]
  topdown-slots-issued OR cpu/topdown-slots-issued/  [Kernel PMU event]
  topdown-slots-retired OR cpu/topdown-slots-retired/ [Kernel PMU event]
  topdown-total-slots OR cpu/topdown-total-slots/    [Kernel PMU event]

通過(guò)查看這些事件,可以了解系統(tǒng)中哪些性能指標(biāo)是可以被監(jiān)測(cè)的,從而在進(jìn)行性能分析時(shí)選擇合適的事件進(jìn)行監(jiān)測(cè)。

(2)顯示統(tǒng)計(jì)信息

perf stat命令用于分析指定程序或命令的性能概況,它會(huì)在程序執(zhí)行結(jié)束后,輸出各類事件的統(tǒng)計(jì)信息,幫助用戶了解程序在運(yùn)行過(guò)程中的性能表現(xiàn)。例如,使用perf stat命令監(jiān)測(cè)ls命令的性能:

$ perf stat ls
Performance counter stats for 'ls':

         0.653782 task-clock (msec)         #    0.691 CPUs utilized
                 0 context-switches          #    0.000 K/sec
                 0 CPU-migrations            #    0.000 K/sec
               247 page-faults               #    0.378 M/sec
         1,625,426 cycles                    #    2.486 GHz
         1,050,293 stalled-cycles-frontend   #   64.62% frontend cycles idle
           838,781 stalled-cycles-backend    #   51.60% backend cycles idle
         1,055,735 instructions              #    0.65  insns per cycle
                                              #    0.99  stalled cycles per insn
           210,587 branches                  #  322.106 M/sec
            10,809 branch-misses             #    5.13% of all branches

       0.000945883 seconds time elapsed

上述輸出中,task-clock表示任務(wù)真正占用的處理器時(shí)間,單位為毫秒;CPUs utilized表示 CPU 的占用率,通過(guò)task-clock除以time elapsed計(jì)算得出;context-switches表示上下文的切換次數(shù);CPU-migrations表示處理器遷移次數(shù),Linux 為了維持多個(gè)處理器的負(fù)載均衡,在特定條件下會(huì)將某個(gè)任務(wù)從一個(gè) CPU 遷移到另一個(gè) CPU;page-faults表示缺頁(yè)異常的次數(shù),當(dāng)應(yīng)用程序請(qǐng)求的頁(yè)面尚未建立、請(qǐng)求的頁(yè)面不在內(nèi)存中,或者請(qǐng)求的頁(yè)面雖然在內(nèi)存中,但物理地址和虛擬地址的映射關(guān)系尚未建立時(shí),都會(huì)觸發(fā)一次缺頁(yè)異常;cycles表示消耗的處理器周期數(shù);instructions表示執(zhí)行的指令數(shù);branches表示遇到的分支指令數(shù);branch-misses表示預(yù)測(cè)錯(cuò)誤的分支指令數(shù);time elapsed表示程序持續(xù)時(shí)間。

perf stat命令還可以通過(guò)-e選項(xiàng)指定要顯示統(tǒng)計(jì)的性能事件,例如:

$ perf stat -e cache-misses,cache-references ls
Performance counter stats for 'ls':

            13,808 cache-misses              #    14.603 M/sec
            53,932 cache-references          #    57.029 M/sec

       0.000945883 seconds time elapsed

上述命令只統(tǒng)計(jì)了cache-misses和cache-references事件,幫助用戶更專注地了解程序在緩存方面的性能表現(xiàn)。

(3)實(shí)時(shí)查看系統(tǒng)性能

perf top命令用于實(shí)時(shí)顯示系統(tǒng)或進(jìn)程的性能統(tǒng)計(jì)信息,它會(huì)動(dòng)態(tài)地展示占用最多 CPU 時(shí)間的函數(shù)或程序,類似于top命令,但更加專注于性能分析。直接運(yùn)行perf top命令,將會(huì)展示系統(tǒng)中所有的進(jìn)程和函數(shù),按照它們占用 CPU 時(shí)間的百分比降序排列:

$ perf top
Samples: 1M of event 'cycles', Event count (approx.): 73891391490
  5.44%  perf                 [.] 0x0000000000023256
  4.86%  [kernel]             [k] _spin_lock
  2.43%  [kernel]             [k] _spin_lock_bh
  2.29%  [kernel]             [k] _spin_lock_irqsave
  1.77%  [kernel]             [k] __d_lookup
  1.55%  libc-2.12.so         [.] __strcmp_sse42
  1.43%  nginx                [.] ngx_vslprintf
  1.37%  [kernel]             [k] tcp_poll

第一列表示符號(hào)引發(fā)的性能事件的比例,默認(rèn)指占用的 CPU 周期比例;第二列表示符號(hào)所在的 DSO(Dynamic Shared Object),可以是應(yīng)用程序、內(nèi)核、動(dòng)態(tài)鏈接庫(kù)、模塊;第三列表示 DSO 的類型,[.]表示此符號(hào)屬于用戶態(tài)的 ELF 文件,包括可執(zhí)行文件與動(dòng)態(tài)鏈接庫(kù),[k]表示此符號(hào)屬于內(nèi)核或模塊;第四列表示符號(hào)名,有些符號(hào)不能解析為函數(shù)名,只能用地址表示。

如果只想關(guān)注特定的進(jìn)程,可以使用-p選項(xiàng),后面跟上進(jìn)程的 PID:

$ perf top -p <PID>

使用-e選項(xiàng)可以指定一個(gè)特定的性能事件,比如關(guān)心緩存未命中(cache misses):

$ perf top -e cache-misses

-a選項(xiàng)用于查看所有 CPU 的數(shù)據(jù),而不僅僅是默認(rèn)的 CPU 0:

$ perf top -a

-K選項(xiàng)可以隱藏內(nèi)核相關(guān)的符號(hào),如果只對(duì)用戶空間的性能感興趣,這個(gè)選項(xiàng)會(huì)非常有用:

$ perf top -K

在運(yùn)行perf top時(shí),需要確保有足夠的權(quán)限,大多數(shù)情況下,需要 root 權(quán)限才能運(yùn)行它。并且,perf top的結(jié)果是實(shí)時(shí)更新的,用戶只需要保持窗口開(kāi)啟,就可以實(shí)時(shí)觀察到系統(tǒng)性能的變化。

(4)記錄與生成報(bào)告

perf record命令用于收集程序運(yùn)行時(shí)的性能數(shù)據(jù),并將數(shù)據(jù)保存到一個(gè)名為perf.data的文件中。例如,使用perf record命令記錄ls命令的性能數(shù)據(jù):

$ perf record -g ls

上述命令中,-g選項(xiàng)用于記錄函數(shù)間的調(diào)用關(guān)系,方便后續(xù)分析函數(shù)的調(diào)用棧。運(yùn)行該命令后,ls命令的性能數(shù)據(jù)會(huì)被記錄到perf.data文件中。

perf report命令用于分析perf record生成的perf.data文件,并顯示分析報(bào)告。運(yùn)行perf report命令后,會(huì)進(jìn)入一個(gè)交互式界面,展示性能數(shù)據(jù)的詳細(xì)分析結(jié)果,包括函數(shù)的調(diào)用關(guān)系、每個(gè)函數(shù)占用的 CPU 時(shí)間等信息:

$ perf report -i perf.data

-i選項(xiàng)用于指定要分析的perf.data文件,如果不指定,默認(rèn)分析當(dāng)前目錄下的perf.data文件。在交互式界面中,可以使用方向鍵上下移動(dòng)選擇不同的函數(shù),按回車鍵可以查看函數(shù)的詳細(xì)信息,如匯編代碼、調(diào)用棧等。還可以使用/鍵進(jìn)行搜索,輸入關(guān)鍵詞來(lái)查找特定的函數(shù)或符號(hào)。

此外,perf report命令還可以通過(guò)其他參數(shù)進(jìn)行更詳細(xì)的分析。例如,-d選項(xiàng)只顯示指定 DSO 的符號(hào),-C選項(xiàng)只顯示指定 comm(觸發(fā)事件的進(jìn)程名)的信息,-S選項(xiàng)只考慮指定符號(hào),-U選項(xiàng)只顯示已解析的符號(hào),-g[type,min,order]選項(xiàng)顯示調(diào)用關(guān)系,具體等同于perf top命令中的-g選項(xiàng) 。通過(guò)這些參數(shù)的組合使用,可以根據(jù)具體需求對(duì)性能數(shù)據(jù)進(jìn)行更有針對(duì)性的分析。

三、Perf的應(yīng)用場(chǎng)景與重要性

3.1性能問(wèn)題定位

perf 在解決系統(tǒng)性能問(wèn)題方面發(fā)揮著至關(guān)重要的作用。當(dāng)面臨 CPU 利用率過(guò)高的情況時(shí),perf 可以通過(guò)收集性能數(shù)據(jù),分析各個(gè)進(jìn)程和函數(shù)對(duì) CPU 資源的占用情況,找出導(dǎo)致高 CPU 使用率的熱點(diǎn)代碼段。例如,通過(guò) perf top 命令可以實(shí)時(shí)顯示當(dāng)前系統(tǒng)中消耗 CPU 周期最多的函數(shù)或指令,快速定位可能存在性能問(wèn)題的代碼區(qū)域。

在 cache miss 過(guò)多的場(chǎng)景下,perf 能夠評(píng)估程序?qū)Ω骷?jí) cache 的訪問(wèn)次數(shù)和丟失次數(shù)。利用 perf stat 命令可以查看與 cache 相關(guān)的性能事件,如 L1-dcache-loads、L1-dcache-load-miss 等,了解 cache 的利用情況。如果發(fā)現(xiàn) cache miss 率過(guò)高,可以進(jìn)一步分析代碼,優(yōu)化數(shù)據(jù)訪問(wèn)模式以提高 cache 命中率。

對(duì)于內(nèi)存 I/O 過(guò)慢的問(wèn)題,perf 可以評(píng)估程序的內(nèi)存訪問(wèn)行為。通過(guò)收集與內(nèi)存相關(guān)的性能事件,如 page-faults、dTLB-loads、dTLB-load-miss 等,分析內(nèi)存訪問(wèn)的效率。如果頻繁出現(xiàn)頁(yè)錯(cuò)誤或者 TLB 未命中,可能需要調(diào)整內(nèi)存分配策略或者優(yōu)化數(shù)據(jù)結(jié)構(gòu),以減少內(nèi)存訪問(wèn)的開(kāi)銷。

此外,perf 還可以生成程序的調(diào)用圖,記錄函數(shù)之間的調(diào)用關(guān)系。通過(guò) perf record 和 perf report 命令,可以收集程序運(yùn)行時(shí)的性能數(shù)據(jù),并生成詳細(xì)的報(bào)告,包括函數(shù)調(diào)用圖、耗時(shí)分布等信息。這有助于理解程序的執(zhí)行流程,找出可能存在性能瓶頸的函數(shù)調(diào)用鏈。

同時(shí),perf 還能檢測(cè)程序的內(nèi)存泄漏問(wèn)題。雖然文章中未明確提及 perf 在內(nèi)存泄漏檢測(cè)方面的具體方法,但可以推測(cè),通過(guò)對(duì)內(nèi)存相關(guān)性能事件的監(jiān)測(cè)以及對(duì)程序運(yùn)行時(shí)內(nèi)存使用情況的分析,可能能夠發(fā)現(xiàn)內(nèi)存泄漏的跡象。例如,持續(xù)觀察內(nèi)存使用量的增長(zhǎng)情況,結(jié)合函數(shù)調(diào)用圖分析可能存在內(nèi)存分配但未釋放的位置。

3.2性能優(yōu)化關(guān)鍵

perf 在程序性能優(yōu)化中具有不可替代的重要性。它可以深入了解應(yīng)用程序的執(zhí)行過(guò)程,為開(kāi)發(fā)者提供關(guān)鍵的性能指標(biāo)和分析結(jié)果,幫助發(fā)現(xiàn)性能瓶頸并進(jìn)行針對(duì)性優(yōu)化。

通過(guò)追蹤 CPU 使用情況,開(kāi)發(fā)者可以了解程序在不同階段對(duì) CPU 資源的消耗情況。利用 perf stat 命令可以獲取諸如 cycles、instructions、IPC 等指標(biāo),分析程序是否充分利用了處理器的特性。如果 IPC 值較低,可能需要優(yōu)化代碼以提高指令的執(zhí)行效率,減少不必要的指令或循環(huán)。

內(nèi)存占用的追蹤也是性能優(yōu)化的重要方面。perf 可以監(jiān)測(cè)內(nèi)存的使用情況,包括內(nèi)存分配、釋放以及 cache 的利用情況。通過(guò)分析這些數(shù)據(jù),可以優(yōu)化內(nèi)存管理策略,減少內(nèi)存碎片,提高內(nèi)存的使用效率。例如,合理調(diào)整數(shù)據(jù)結(jié)構(gòu)的大小和布局,避免頻繁的內(nèi)存分配和釋放操作。

函數(shù)調(diào)用堆棧的追蹤可以幫助開(kāi)發(fā)者找出熱點(diǎn)函數(shù),即那些消耗大量資源的函數(shù)。利用 perf top 和 perf record 命令可以收集函數(shù)級(jí)別的性能數(shù)據(jù),確定哪些函數(shù)是性能瓶頸所在。針對(duì)熱點(diǎn)函數(shù),可以進(jìn)行算法優(yōu)化或代碼重構(gòu),提高其執(zhí)行效率。

四、常見(jiàn)性能問(wèn)題分析

⑴性能測(cè)試大致分以下幾個(gè)步驟:

  1. 需求分析
  2. 腳本準(zhǔn)備
  3. 測(cè)試執(zhí)行
  4. 結(jié)果整理
  5. 問(wèn)題分析

需求描述:有一個(gè)服務(wù),啟動(dòng)時(shí)會(huì)加載一個(gè)1G的詞表文件到內(nèi)存,請(qǐng)求來(lái)了之后,會(huì)把請(qǐng)求詞去詞表里做模糊匹配,如果匹配到了就向一個(gè)后端服務(wù)發(fā)送一條http請(qǐng)求,拿回?cái)?shù)據(jù)之后,返回給客戶端的同時(shí),向mysql記錄請(qǐng)求的唯一標(biāo)識(shí)和一個(gè)請(qǐng)求次數(shù)的標(biāo)記;

  • 其中有幾個(gè)關(guān)鍵函數(shù)
  • 模糊匹配(fuzzyMatching)
  • 后端請(qǐng)求函數(shù)(sendingRequest)
  • 拼裝請(qǐng)求函數(shù)(buildResponse)
  • 記錄mysql請(qǐng)求次數(shù)標(biāo)記(signNum)

問(wèn)題及分析:

第一組:完全隨機(jī)請(qǐng)求詞,qps達(dá)到1k時(shí),服務(wù)器未見(jiàn)異常,cpu、內(nèi)存、帶寬均未滿,qps無(wú)法繼續(xù)提升;

分析:由于此服務(wù)后端連接了其它服務(wù),所以在壓測(cè)之前,要確認(rèn)后端服務(wù)不會(huì)成為瓶頸點(diǎn),目前的狀態(tài)很可能是后端服務(wù)限制了被測(cè)服務(wù)的性能;此時(shí)可以檢查后端服務(wù)所在機(jī)器的各項(xiàng)指標(biāo),或者查看本機(jī)的連接狀況,一般后端服務(wù)無(wú)法處理,而被測(cè)服務(wù)又會(huì)一直向后面請(qǐng)求的話,timewait狀態(tài)的連接會(huì)變得比較多;

第二組:解決后端服務(wù)的問(wèn)題后,第二組使用平均30個(gè)字的請(qǐng)求詞,來(lái)打壓,qps到400時(shí),cpu load已滿;

分析:這種情況明顯是由于fuzzyMatching函數(shù)計(jì)算效率的問(wèn)題導(dǎo)致cpu滿載,從而無(wú)法提升qps,使響應(yīng)時(shí)間不斷增大,此時(shí)可以通過(guò)perf+火焰圖來(lái)確定整個(gè)處理請(qǐng)求過(guò)程中響應(yīng)時(shí)間長(zhǎng)的函數(shù);此時(shí)需要評(píng)估壓測(cè)數(shù)據(jù)是否合理,如果線上平均請(qǐng)求詞只有2個(gè)的時(shí)候,此組測(cè)試明顯不合理,此時(shí)要開(kāi)發(fā)進(jìn)行性能優(yōu)化就是浪費(fèi)時(shí)間的;如果評(píng)估測(cè)試數(shù)據(jù)合理,可以再次更換短詞數(shù)據(jù)進(jìn)行壓測(cè)驗(yàn)證猜測(cè);

第三組:解決了上述兩個(gè)問(wèn)題之后,使用完全隨機(jī)請(qǐng)求詞,qps到達(dá)3k后降低至1k,然后再次提升到3k,如此反復(fù);

分析:此時(shí)關(guān)注一下各項(xiàng)指標(biāo),排除了以上的問(wèn)題的話,操作mysql慢的問(wèn)題可能性大一些,對(duì)這種需要高并發(fā)的系統(tǒng)來(lái)說(shuō),直接讀寫mysql不是個(gè)聰明的解決方案,一般會(huì)用redis做一層緩存,這里說(shuō)道的另一個(gè)問(wèn)題就是開(kāi)發(fā)設(shè)計(jì)不合理,導(dǎo)致的性能問(wèn)題;

第四組:將后端換做真實(shí)的服務(wù)來(lái)做整體壓測(cè),發(fā)現(xiàn)qps最高只能到300,此時(shí)檢查各項(xiàng)指標(biāo),發(fā)現(xiàn)入口帶寬占滿了;

分析:這次問(wèn)題比較明顯,后端服務(wù)返回內(nèi)容過(guò)大,導(dǎo)致帶寬被占滿,此時(shí)依然需要評(píng)估需求:1、是否需要后端返回的所有數(shù)據(jù)內(nèi)容;2、評(píng)估更換萬(wàn)兆網(wǎng)卡的性價(jià)比;3、是否可以通過(guò)技術(shù)手段優(yōu)化帶寬占用,比如把一次請(qǐng)求分散到多組服務(wù)的多個(gè)請(qǐng)求;

⑵perf+火焰圖定位函數(shù)問(wèn)題

這里簡(jiǎn)單說(shuō)一下如何使用perf+火焰圖來(lái)直觀的定位性能問(wèn)題:

Perf 擁有了眾多的性能分析能力,舉例來(lái)說(shuō),使用 Perf 可以計(jì)算每個(gè)時(shí)鐘周期內(nèi)的指令數(shù),稱為 IPC,IPC 偏低表明代碼沒(méi)有很好地利用 CPU。Perf 還可以對(duì)程序進(jìn)行函數(shù)級(jí)別的采樣,從而了解程序的性能瓶頸究竟在哪里等等。Perf 還可以替代 strace,可以添加動(dòng)態(tài)內(nèi)核 probe 點(diǎn),還可以做 benchmark 衡量調(diào)度器的好壞。

  • 使用舉例:perf record -e cpu-clock -g -p 11110 -o data/perf.data sleep 30
  • -g 選項(xiàng)是告訴perf record額外記錄函數(shù)的調(diào)用關(guān)系 -e cpu-clock 指perf record監(jiān)控的指標(biāo)為cpu周期 -p 指定需要record的進(jìn)程pid

⑶生成火焰圖

①第一步:使用壓力測(cè)試工具對(duì)程序進(jìn)行打壓,壓到程序拐點(diǎn);

$sudo perf record -e cpu-clock -g -p 11110
Ctrl+c結(jié)束執(zhí)行后,在當(dāng)前目錄下會(huì)生成采樣數(shù)據(jù)perf.data.

②第二步:用perf 工具對(duì)perf.data進(jìn)行解析

perf -i perf.data &> perf.unfold

⑶第三步:將perf.unfold中的符號(hào)進(jìn)行折疊:

./stackcollapse-perf.pl perf.unfold &> perf.folded

④最后生成svg圖:

./flamegraph.pl perf.folded > perf.svg

到這兒可以生成函數(shù)調(diào)用火焰圖,如下圖:

圖片圖片

原生的perf可以直接定位C/C++的程序,通常編譯debug版本的程序能看到更多的信息,java、go等語(yǔ)言可以通過(guò)各自定制的工具來(lái)生成,原理類似;通過(guò)火焰圖可以輕松定位到哪個(gè)函數(shù)的處理時(shí)間最長(zhǎng),從而找到問(wèn)題所在。

責(zé)任編輯:武曉燕 來(lái)源: 深度Linux
相關(guān)推薦

2025-04-01 02:00:22

2021-11-14 07:29:55

Linux 內(nèi)核靜態(tài)追蹤Linux 系統(tǒng)

2021-11-15 04:00:07

Linux 內(nèi)核動(dòng)態(tài)

2010-01-07 13:44:54

Linux內(nèi)核代碼

2009-06-17 17:00:03

2020-11-20 07:55:55

Linux內(nèi)核映射

2021-03-06 22:41:06

內(nèi)核源碼CAS

2011-06-03 09:26:11

2009-06-17 13:03:42

Linux內(nèi)核

2025-04-18 04:05:00

2022-08-03 11:00:20

Linux內(nèi)核

2009-06-17 11:58:19

Linux

2022-07-14 08:02:57

Netty網(wǎng)絡(luò)模塊

2021-10-06 09:46:17

trace-cmd追蹤內(nèi)核Linux

2023-05-08 08:05:42

內(nèi)核模塊Linux

2020-04-01 10:28:12

Apache HBas數(shù)據(jù)結(jié)構(gòu)算法

2010-01-07 10:22:49

Linux內(nèi)核

2011-01-04 18:15:21

2009-11-16 14:15:51

PHP上傳多個(gè)文件

2024-01-19 12:48:00

Redis存儲(chǔ)數(shù)據(jù)庫(kù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)