Linux perf工具簡介與使用

Perf 簡介


Perf 是用來進行軟件性能分析的工具。(per-tools 是性能優化大師brendan gregg 就有perf 以及ftrace 編寫的性能優化工具集
提供了io 、網絡、系統調用。。。大部分方面的性能分析工具)

通過它,應用程序可以利用 PMU,tracepoint 和內核中的特殊計數器來進行性能統計。它不但可以分析指定應用程序的性能問題 (per thread),也可以用來分析內核的性能問題,當然也可以同時分析應用代碼和內核,從而全面理解應用程序中的性能瓶頸。

最初的時候,它叫做 Performance counter,在 2.6.31 中第一次亮相。此後他成爲內核開發最爲活躍的一個領域。在 2.6.32 中它正式改名爲 Performance Event,因爲 perf 已不再僅僅作爲 PMU 的抽象,而是能夠處理所有的性能相關的事件。

使用 perf,您可以分析程序運行期間發生的硬件事件,比如 instructions retired ,processor clock cycles 等;您也可以分析軟件事件,比如 Page Fault 和進程切換。

這使得 Perf 擁有了衆多的性能分析能力,舉例來說,使用 Perf 可以計算每個時鐘週期內的指令數,稱爲 IPC,IPC 偏低表明代碼沒有很好地利用 CPU。Perf 還可以對程序進行函數級別的採樣,從而瞭解程序的性能瓶頸究竟在哪裏等等。Perf 還可以替代 strace,可以添加動態內核 probe 點,還可以做 benchmark 衡量調度器的好壞。

人們或許會稱它爲進行性能分析的“瑞士軍刀”,但我不喜歡這個比喻,我覺得 perf 應該是一把世間少有的倚天劍。

金庸筆下的很多人都有對寶刀的癖好,即便本領低微不配擁有,但是喜歡,便無可奈何。我恐怕正如這些人一樣,因此進了酒館客棧,見到相熟或者不相熟的人,就要興沖沖地要講講那倚天劍的故事。

 

背景知識


有些背景知識是分析性能問題時需要了解的。比如硬件 cache;再比如操作系統內核。應用程序的行爲細節往往是和這些東西互相牽扯的,這些底層的東西會以意想不到的方式影響應用程序的性能,比如某些程序無法充分利用 cache,從而導致性能下降。比如不必要地調用過多的系統調用,造成頻繁的內核 / 用戶切換。等等。方方面面,這裏只是爲本文的後續內容做一些鋪墊,關於調優還有很多東西,我所不知道的比知道的要多的多。

性能相關的處理器硬件特性,PMU 簡介

當算法已經優化,代碼不斷精簡,人們調到最後,便需要斤斤計較了。cache 啊,流水線啊一類平時不大注意的東西也必須精打細算了。

硬件特性之 cache

內存讀寫是很快的,但還是無法和處理器的指令執行速度相比。爲了從內存中讀取指令和數據,處理器需要等待,用處理器的時間來衡量,這種等待非常漫長。Cache 是一種 SRAM,它的讀寫速率非常快,能和處理器處理速度相匹配。因此將常用的數據保存在 cache 中,處理器便無須等待,從而提高性能。Cache 的尺寸一般都很小,充分利用 cache 是軟件調優非常重要的部分。

 

 

硬件特性之流水線,超標量體系結構,亂序執行


提高性能最有效的方式之一就是並行。處理器在硬件設計時也儘可能地並行,比如流水線,超標量體系結構以及亂序執行。

處理器處理一條指令需要分多個步驟完成,比如先取指令,然後完成運算,最後將計算結果輸出到總線上。在處理器內部,這可以看作一個三級流水線,如下圖所示:

圖 1. 處理器流水線

圖 1. 處理器流水線

指令從左邊進入處理器,上圖中的流水線有三級,一個時鐘週期內可以同時處理三條指令,分別被流水線的不同部分處理。

超標量(superscalar)指一個時鐘週期發射多條指令的流水線機器架構,比如 Intel 的 Pentium 處理器,內部有兩個執行單元,在一個時鐘週期內允許執行兩條指令。

此外,在處理器內部,不同指令所需要的處理步驟和時鐘週期是不同的,如果嚴格按照程序的執行順序執行,那麼就無法充分利用處理器的流水線。因此指令有可能被亂序執行。

上述三種並行技術對所執行的指令有一個基本要求,即相鄰的指令相互沒有依賴關係。假如某條指令需要依賴前面一條指令的執行結果數據,那麼 pipeline 便失去作用,因爲第二條指令必須等待第一條指令完成。因此好的軟件必須儘量避免這種代碼的生成。

 

硬件特性之分支預測


分支指令對軟件性能有比較大的影響。尤其是當處理器採用流水線設計之後,假設流水線有三級,當前進入流水的第一條指令爲分支指令。假設處理器順序讀取指令,那麼如果分支的結果是跳轉到其他指令,那麼被處理器流水線預取的後續兩條指令都將被放棄,從而影響性能。爲此,很多處理器都提供了分支預測功能,根據同一條指令的歷史執行記錄進行預測,讀取最可能的下一條指令,而並非順序讀取指令。

分支預測對軟件結構有一些要求,對於重複性的分支指令序列,分支預測硬件能得到較好的預測結果,而對於類似 switch case 一類的程序結構,則往往無法得到理想的預測結果。

上面介紹的幾種處理器特性對軟件的性能有很大的影響,然而依賴時鐘進行定期採樣的 profiler 模式無法揭示程序對這些處理器硬件特性的使用情況。處理器廠商針對這種情況,在硬件中加入了 PMU 單元,即 performance monitor unit。

PMU 允許軟件針對某種硬件事件設置 counter,此後處理器便開始統計該事件的發生次數,當發生的次數超過 counter 內設置的值後,便產生中斷。比如 cache miss 達到某個值後,PMU 便能產生相應的中斷。

捕獲這些中斷,便可以考察程序對這些硬件特性的利用效率了。

 

perf 的基本使用


說明一個工具的最佳途徑是列舉一個例子。

考查下面這個例子程序。其中函數 longa() 是個很長的循環,比較浪費時間。函數 foo1 和 foo2 將分別調用該函數 10 次,以及 100 次。

清單 1. 測試程序 t1

//test.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(); 
}

找到這個程序的性能瓶頸無需任何工具,肉眼的閱讀便可以完成。Longa() 是這個程序的關鍵,只要提高它的速度,就可以極大地提高整個程序的運行效率。

但,因爲其簡單,卻正好可以用來演示 perf 的基本使用。假如 perf 告訴您這個程序的瓶頸在別處,您就不必再浪費寶貴時間閱讀本文了。

未完。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章