2009-01-20 34 views
19

當我在一個大學項目上工作時,我使用了一個由大一學生製作的項目內部分析器,它非常基本,但是它的任務是減少代碼的兩個點之間的時間並給出統計數據。代碼分析器如何工作?

現在,專業分析器如何工作?它預處理代碼插入檢查點或類似的東西?它是否使用調試數據讀取二進制代碼以捕獲函數的調用位置?

謝謝。

回答

22

有很多不同的分析器以不同的方式工作。

常用的分析器只是定期檢查正在運行的程序,以查看當前正在執行的程序指令(程序計數器)和哪些例程調用當前函數(調用棧)。這種類型的採樣 profiler可以使用標準二進制文件,但如果您有調試符號來計算程序中指定地址的代碼行,它將更加有用。

除了定期採樣,還可以使用處理器性能計數器在一定數量的事件(如緩存未命中)之後進行採樣,這將幫助您查看由於內存訪問而導致程序的哪些部分變慢。其他分析器涉及重新編譯程序以插入指令(稱爲儀器)以計算每個連續指令集(基本塊)被執行的頻率,或者甚至可以記錄執行基本塊的序列,或者在某些地方記錄變量的內容。

儀器方法可以爲您提供所有您想要的精度和數據,但會降低程序速度並改變其性能特徵。相比之下,使用基於抽樣的方法,您可以根據所獲得的配置文件數據的準確性,根據需要運行該程序的時間長度來調整性能影響。

2

它取決於正在分析的代碼的類型,例如.NET CLR爲代碼分析器提供facility。在處理託管代碼時,可以重寫中間代碼以注入自定義鉤子。您也可以分析應用程序的堆棧跟蹤。操作系統可以提供分析的手段,例如Windows有performance counters。處理嵌入式代碼時,您可以模擬/替代底層硬件以有效監視系統性能。

+0

你是什麼意思的「託管代碼」? – tunnuz 2009-01-20 10:19:38

+0

http://en.wikipedia.org/wiki/Managed_code – aku 2009-01-20 10:21:50

13

有兩種常見的性能分析策略(無論如何都是基於虛擬機的語言):儀器和採樣。

每次方法啓動和完成時,插裝檢查點並通知分析器。這可以通過JIT /解釋器完成,也可以通過後期正常編譯但預執行階段完成,該階段僅更改可執行文件。這可能會對性能產生非常顯着的影響(從而扭曲任何時序結果)。儘管獲得準確的數字很好。

採樣會定期詢問VM對於所有線程都是什麼樣的堆棧跟蹤,並以此方式更新其統計信息。這通常會影響性能,但會產生較不準確的通話計數。

0

gprof in * nix,在編譯和鏈接時使用-pg,將一些額外的代碼注入到目標代碼中。然後通過運行gprof,由注入的代碼生成報告文件。

2

正如Jon Skeet上面寫到的那樣,有兩種策略:儀器和採樣。

儀器手動和自動完成。在手動情況下:開發人員手動插入代碼來跟蹤感興趣的代碼區域的開始/結束。例如一個簡單的「StartTimer」和「EndTimer」。某些分析器工具也可以自動完成此操作 - 爲此,分析器需要對代碼執行靜態分析,即分析代碼並確定重要的檢查點,如特定方法的開始/結束。對於支持反射的語言(例如任何.net語言),這是最容易的。使用「反射」,剖析器能夠重建整個源代碼樹(以及調用圖)。

採樣由探查器完成,它會查看二進制代碼。分析器還可以使用Hooks或陷阱Windows事件/消息等技術來進行性能分析。

儀器和採樣方法都有自己的開銷。開銷的量取決於 - 例如,如果採樣頻率設置爲較高值,則剖析本身可以對所報告的性能作出顯着貢獻。

儀器與採樣: 它不像一個比另一個更好。兩者都有自己的位置。

最好的方法是從基於採樣的分析器開始,並查看整個系統級別。運行採樣器並查看系統資源使用情況:內存,硬盤,網絡,CPU。

從上面確定正在窒息的資源。

通過上述信息,您現在可以將代碼添加到您的代碼中,以查明罪魁禍首。例如,如果內存是最常用的資源,那麼它將有助於檢測與內存分配相關的代碼。請注意,使用儀器,您真的專注於代碼的特定區域。