效能分析

軟件工程中,效能分析(performance analysis,也稱為profiling),是以收集程式執行時資訊為手段研究程式行為的分析方法,是一種動態程式分析英語Dynamic program analysis的方法。

效能分析量測像是程式的空間或時間複雜度特定指令的使用情形英語instruction set simulator、函數呼叫的頻率及執行時間等。效能分析的目的在於決定程式的哪個部分應該被最佳化英語Program optimization,從而提高程式的速度或者主記憶體使用效率。

效能分析可以由程式的原始碼或是可執行檔進行。一般會使用稱為效能分析工具(profiler)的工具進行。效能分析工具會使用許多不同的技術,可能是以事件為基礎(Event-based)的、統計的、指令導向的、仿真的方法。效能分析工具常用在效能工程英語Performance engineering的過程中。

效能分析工具

 
CodeAnalyst英語CodeAnalyst效能分析工具的圖像輸出

"若要了解程式行為,程式分析工具非常重要。電腦架構分析師需要這類工具來評估程式在新的系統結構中運作的情形。軟件撰寫者需要這類工具來分析程式,並分析出其中關鍵的區塊。編譯器撰寫者需要這類工具來評估其指令排程分支預測演算法運作的情形" -- (ATOM, PLDI, '94)

效能分析工具使用廣泛的技術手段收集數據,包括硬件中斷代碼指令英語Instrumentation (computer programming)作業系統hooking英語hooking、CPU內建的效能計數暫存器英語Hardware performance counter,等等。

效能分析輸出會是:

  • 觀察到的事件的統計摘要(概要檔案)
摘要設定檔資訊通常會根據事件發生的原始碼陳述式進行註釋顯示,因此測量數據的大小與程式的代碼大小成線性關係。
/* ------------ 源代碼------------------------- 發行次數 */            
0001             IF X = "A"                     0055
0002                THEN DO                      
0003                  ADD 1 to XCOUNT           0032
0004                ELSE
0005             IF X = "B"                     0055


  • 所有事件的記錄流(亦稱蹤跡,英文「trace」)
事件的記錄流則與指令路徑長度英語Instruction path length成線性關係,也就是和執行時長成線性關係。由於資料量過大,有時記錄會不切實際。所以,有些程式分析工具可以設置在某特殊條件下才啟動事件蹤跡的記錄,在另外特殊條件下結束事件蹤跡的記錄。
對於順序執行的程式,通常輪廓就足夠了。但平行計算程式的效能問題(等待訊息或者同步問題)和事件的時間順序有關,因此需要全部的蹤跡才能找到問題。
  • hypervisor持續性的互動監控(針對事件連續性或週期性顯示在螢幕上)
在觀看在執行程式的相關度量時.可在任意時刻啟動或結束事件蹤跡的記錄,也可以在一些關鍵的點上暫停非同步的程式來看和其他平行處理程式之間的互動關係。

歷史

早在1970年代,IBM System/360IBM System/370英語IBM/370的平台就有效能分析工具,一般是用計時器中斷在固定的時間紀錄程式狀態字英語Program status word(PSW)來偵測程式執行時的「過熱點」(hot spots)[來源請求]。這是早期使用抽樣方式進行效能分析的範例之一。在1974年時,指令集仿真器英語instruction set simulator就允許完整的事件蹤跡,以及其他效能監控的機能。

以效能分析工具為主的UNIX程式分析至少可以回溯到1979年,當時Unix系統有一個基礎工具prof,可以列出每一個函數,也列出此函數總共花了多少時間。1982年時gprof工具延伸此概念,可以列出完整的函數調用圖[1]

1994年時,迪吉多的Amitabh Srivastava和Alan Eustace提出了描述ATOM的論文[2]。ATOM是一個平台,可以將程式配合其效能分析工具調整,在編譯期間,ATOM會在要分析的程式中加入程式碼,而加入的程式碼會輸出分析資料,這種修改程式,輸出自身份析資料的技術,稱為邏輯注入英語Instrumentation (computer programming)

2004年時,gprof和ATOM論文都出現在前50個最具影響力的程式語言設計和實現會議英語Conference on Programming Language Design and Implementation(PLDI)論文中[3]


以輸出方式分類

一般效能剖析器

一般效能剖析器(flat profiler)根據函數呼叫計算平均的函數呼叫次數,而且不會根據被呼叫函數或是執行脈絡(context)細分函數呼叫次數。

函數調用圖效能剖析器

函數調用圖效能剖析器(call graph profiler)[4]會顯示函數被呼叫的次數及頻率,也會列出函數調用鏈(call-chains),有些軟件會列完整的調用鏈,有些不會。

輸入敏感效能剖析器

輸入敏感效能剖析器(input-sensitive profiler)[5][6][7]將效能度量與輸入工作負載特徵(例如輸入大小或輸入值)相關聯,相比於一般效能剖析器或呼叫圖剖析器增加了一個維度。它會生成圖表描述應用程式效能隨其輸入的變化情況。

以分析方式的分類

效能剖析器本身也是程式,可以在被分析程式執行時收集相關資訊,來分析該程式。根據收集到資訊的細微度,以及收集資訊的方式,可以分為事件為基礎的效能剖析器,或是統計式的效能剖析器。有些效能剖析器為了收集資訊,會中斷程式的執行,因此在時間量測上有一定的解像度限制。

事件為基礎的效能剖析器

以下列出的程式語言有事件為基礎的效能剖析器:

  • JavaJVMTI英語Java Virtual Machine Tools Interface(JVM工具介面)API,以前稱為JVMPI(JVM效能分析介面),提供給效能剖析器的hook,可以抓到像函數呼叫、類別載入、解除安裝、線程的進入及離開等事件。
  • .NET框架:利用效能分析的API,可以連接到像是COM伺服器的效能分析代理器(profiling agent)。像Java一様,在執行會提供許多回呼函數給代理器,可以捕捉到像是方法JIT/進入/離開,物件創建及其他。特別的是效能分析代理器可以用任意方式改寫目的應用程式的位元組碼。
  • Python:Python的效能分析包括profile模組,以調用函數圖為基礎的hotshot,以及用'sys.setprofile'函數來捕捉像c_{call,return,exception}及python_{call,return,exception}的事件。
  • Ruby:Ruby也用類似Python的效能分析介面。目前有在profile.rb中的一般效能剖析器及相關模組。

統計式的效能剖析器

有些效能剖析器是用取樣的方式運作。取様式的效能剖析器利用作業系統中斷,在固定時間取様目的程式的呼叫棧。取様式的效能剖析器在數值上較不精準,但對目的程式執行時間的影響最小,允許目的程式可以在接近全速的速度下運作。

所得到的資料不是精準值,只是統計上的近似值而已。「實際誤差的量一般會大於一個取樣時間。若某一數值是取様時間的n倍,其誤差約為n倍取樣時間的平方根。」[8]

在實務上統計式的效能剖析器會比其他的分析方式更能知道目的程式各部份占的比例,而且相較之下有較少的邊際效應(例如記憶體快取或是指令解碼的管道線等),由於統計式的效能剖析器對程式執行速度的影響較小。因此可以偵測到一些其他方式偵測不到的問題。這種方式可以看出用戶模式及可中斷系統模式(例如系統呼叫)分別佔的時間。

不過由於系統程式需處理中斷,仍然會花一些CPU的執行周期,分散快取的讀取,而且無法分辨在不可中斷核心模式下的行為。

有些特製的硬件可以克服這類的問題:有些最近MIPS微理器中,JTAG介面有一個PCSAMPLE暫存器,可以用一種無法偵測到的方式來取様程式計數器。

最常用的統計式的效能剖析器包括AMDCodeAnalyst蘋果公司Shark(OSX)、oprofile(Linux)[來源請求]IntelVTune英語VTune及Parallel Amplifier(Intel Parallel Studio英語Intel Parallel Studio的一部份)。

插裝型的效能剖析器

有些效能分析可以用插裝英語instrumenting(也稱為邏輯注入)的方式處理目的程式,也就是在目的程式中加入額外指令來收集需要的資訊。

程式的插裝會影響程式的效能,可能會出現不精確的結果及 heisenbug(捉摸不定,不易重現的bug)。插裝一定會對程式執行有些影響,常見的情形是使程式變慢。不過插裝可以特定只針對部份程式,而且可以小心控制以使影響降到最低。其對於特定程式的影響是看插裝放置的位置,以及捕捉蹤跡(trace)的機制。有些處理器有硬件支援可以捕捉蹤跡,插裝可以只佔一個機器語言週期的時間。一般可以從結果中移除插裝的影響。

gprof是一個同時用插裝及取様的效能剖析器的例子。插裝用來取得被呼叫函數的資訊,而實際花的時間則是由取様方式來獲得。

插裝是決定效能剖析器可控制程度及時間解像度的關鍵。以下是一些方式的分類。

  • 手動:是由程式設計者加入指令,在執行時計算相關資訊,例如計算事件或是呼叫像是應用程式響應測試英語Application Response Measurement(ARM)標準的API
  • 原始碼層級自動處理:依照插裝政策,利用自動化工具自動在原始碼中加入instrumentation,像Parasoft英語Parasoft公司的Insure++英語Insure++
  • 中間語言:在匯編語言或是bytecode中加入針對多種高階語言的instrumentation,,例如OpenPATOpenPAT英語OpenPATOpenPAT
  • 編譯器協助:像gprof和Quantify都是這類的例子,像用gcc -pg ...可以使用gprof,用quantify g++ ...可以使用Quantify。
  • 二進位翻譯:此工具在編譯好的可執行檔中加入instrumentation,例如ATOM。
  • 執行時插裝:代碼直接在執行前修改,工具可以完成的監控及控制程式的執行,例如用Pin英語Pin (Computer Program)ValgrindDynamoRIO英語DynamoRIO
  • 執行時注入:修改程度比執行時插裝要小,代碼在執行時修改,令加入跳躍到協助用函數的指令,例如和DynInst英語DynInst

直譯器式的插裝

  • 直譯器式除錯選項,可以在直譯器處理每個目的指令時,收集效能量度的相關資訊。像位元組碼控制表JIT的直譯器都在目標碼執行時有完整的控制能力,因此有機會收集到非常全面的資料。

hypervisor/模擬器(simulator)

相關條目

參考資料

  1. ^ gprof: a Call Graph Execution Profiler頁面存檔備份,存於互聯網檔案館) // Proceedings of the SIGPLAN '82 Symposium on Compiler Construction, SIGPLAN Notices, Vol. 17, No 6, pp. 120-126; doi:10.1145/800230.806987
  2. ^ Amitabh Srivastava and Alan Eustace, "Atom: A system for building customized program analysis tools", 1994 (download頁面存檔備份,存於互聯網檔案館)) // Proceeding PLDI '94 Proceedings of the ACM SIGPLAN 1994 conference on Programming language design and implementation. Pages 196 - 205, doi:10.1145/773473.178260
  3. ^ 20 Years of PLDI (1979–1999): A Selection, Kathryn S. McKinley, Editor. [2013-12-14]. (原始內容存檔於2017-10-18). 
  4. ^ Graham, Susan L.; Kessler, Peter B.; Mckusick, Marshall K. Gprof: A call graph execution profiler. Proceedings of the 1982 SIGPLAN symposium on Compiler construction - SIGPLAN '82 (Boston, Massachusetts, United States: ACM Press). 1982: 120–126. ISBN 978-0-89791-074-3. doi:10.1145/800230.806987 (英語). 
  5. ^ Coppa, Emilio; Demetrescu, Camil; Finocchi, Irene. Input-Sensitive Profiling. IEEE Transactions on Software Engineering. 2014-12-01, 40 (12): 1185–1205 [2022-02-18]. ISSN 0098-5589. doi:10.1109/TSE.2014.2339825. (原始內容存檔於2022-02-18). 
  6. ^ Zaparanuks, Dmitrijs; Hauswirth, Matthias. Algorithmic profiling. Proceedings of the 33rd ACM SIGPLAN Conference on Programming Language Design and Implementation (Beijing China: ACM). 2012-06-11: 67–76 [2022-02-18]. ISBN 978-1-4503-1205-9. doi:10.1145/2254064.2254074. (原始內容存檔於2022-02-18) (英語). 
  7. ^ Lin, Hai-Xiang (編). Euro-Par 2009 – Parallel Processing Workshops: HPPC, HeteroPar, PROPER, ROIA, UNICORE, VHPC, Delft, The Netherlands, August 25-28, 2009, Revised Selected Papers. Lecture Notes in Computer Science 6043. Berlin, Heidelberg: Springer Berlin Heidelberg https://link.springer.com/10.1007/978-3-642-14122-5. 2010. ISBN 978-3-642-14121-8. doi:10.1007/978-3-642-14122-5 (英語).  缺少或|title=為空 (幫助)
  8. ^ Statistical Inaccuracy of gprof Output 互聯網檔案館存檔,存檔日期2012-05-29.

外部連結