在上一章中,咱們研究了爲何性能很重要,甚至診斷了一個簡單的性能問題。在本章中,咱們將總覽執行性能分析的其餘方法。爲了證實這些問題,咱們將診斷與練習1.1中調查的相同問題。咱們還將對比這些不一樣的方式,並回顧它們的利弊。然而,在冒險經過這些替代方案以前,讓咱們首先更好地瞭解衡量時間的實際含義。c++
測量時間是全部與性能相關的工做的核心。性能分析旨在優化兩個關鍵維度的系統運行:shell
固然,第一項要求咱們可以測量時間間隔。正如咱們將看到的,第二項也須要時間測量。在當代計算機系統上,有許多不一樣的方法能夠測量時間,從基於秒錶的粗製濫造測量,到基於高精度高頻性能計數器的測量。數據庫
測量場景持續時間的最簡單、最天真的方法之一是使用常規秒錶(stopwatch)。正如您能夠想象的那樣,這種方法缺少準確性,並且很是勞動密集型——例如,嘗試用秒錶測量計算機啓動幾十次所需的時間(以得到統計準確性),您很快就會意識到這種方法不具有擴展性。此外,秒錶不足以測量須要毫秒級精度的場景。即便是咱們中最優秀的人,在使用秒錶時,一般也不能精確地記準時間。幸運的是,有更好的方法來衡量和報告場景持續時間。編程
大多數剛接觸性能工程的人都是從使用秒錶般的方法測量場景的持續時間(例如用戶交互的響應性)開始的。固然,這隻適用於要花至關長時間的場景,這種場景通常都會給用戶展現進度條。顯然,對於足夠快的場景(例如響應式用戶交互),依賴人類感知的測量方法根本不起做用。特別是,手動秒錶測量中涉及的偏差一般與您想要測量的活動具備相同的數量級。不過,秒錶測量是你常用的東西,由於它的簡單性和缺少更好的工具。秒錶的精度在用於驗證較長運行場景的問題時有時仍然能夠接受,。c#
即便在秒錶接近精度可能足夠的場景中(即測量延長場景時),您仍然須要確保統計的健全性。您能夠經過屢次測量場景延遲,而後計算中位數和百分位數來實現此目的。解決此問題的一種常見方法是編寫測量的工做流腳本,並在腳本中的正確點包括時間戳探測器。在Windows的腳本環境中,您能夠在CMD控制檯執行%time%
或者在PowerShell控制檯執行Get-Date
命令來獲取時間差。當使用重複測量持續比較長時間的場景時,這種時間測量能夠爲該場景的持續時間提供足夠好的時間統計。%time%
和Get-Date
後面的時間源稱爲系統時間源,其精度範圍爲1-15.625ms(後者是默認值),這依賴於時間源是怎麼配置的。windows
雖然從技術上講,系統時間精度應該足夠好,能夠測量須要300-500毫秒的場景,但因爲實際運行這些系統命令的成本和解釋命令提示符環境的開銷,從腳本中這樣作是不實際的。要測量<300~500ms精度的場景,您須要在代碼中加時間統計代碼,而再也不能經過腳原本測量。(即在代碼中的興趣點添加時間戳標記)。系統時間能夠在代碼中使用,但正如咱們稍後將向您展現的那樣,對於許多感興趣的場景,您確實但願經過使用所謂的高精度時間源得到更精確的時間。數組
注意:正如咱們稍後將更正式地看到的那樣,300-500ms處於系統可視響應用戶輸入的可接受響應時間的上限。有些人把這叫作足夠快,而另外一些人則說這差點沒響應。因爲這本書的重點是確保用戶體驗很是快速和快速(固然,在用戶的腦海中瞬間將是理想的目標),咱們顯然須要一種方法來精確測量短於300ms的時間間隔。服務器
計算機系統中有不少東西能夠跟蹤時間。根據系統架構,您可能會遇到ACPI計時器、PM計時器、CMOS計時器、HPET計時器等時間源。這些時間源統稱爲硬件計時器。處理器自己還提供TSC(時間戳計數器)時間測量工具,可經過讀取時間戳計數器(RDTSC)指令訪問該工具。在測量時間時,您一般不會直接接觸到這些時間源。然而,操做系統確實利用它們來實現各類時間測量API,用於系統時間和高精度時間測量。網絡
注意:在.NET中,測量時間的常見方法是使用System.Dias.StopWatch類。請注意,此類不保證高精度測量——此類支持是系統特定的。要檢查StopWatch類是否確實爲您提供了高精度時間測量,您可使用如下C#代碼:架構
System.Diagnostics.StopWatch( (IsHighResolution==TRUE) ? QPC : SystemTime)
將測量場景的持續時間映射到測量它們所需的測量精度,並枚舉典型運行環境的相應Windows API和命令,獲得下面的圖示
正如你所看到的,秒錶測量只涵蓋了很是小的場景範圍。人眼顯然對它能夠記錄的場景持續時間有一個下限。同時它能夠跟蹤的場景的持續時間也有上限。超出這一時間範圍的情景(即很是快的情景<2s或相對緩慢的情景>5min)不適合取決於人類反應的測量。
爲了解決人類對反應時間和注意力範圍的限制,咱們能夠依靠自動化。經過腳本獲取的時間測量足夠好,能夠測量超過一秒鐘的時間跨度。精度若是要求更低的話,則從腳本中調用時間測量命令的時間就會開始影響您的測量。爲了更精確,您須要在代碼中添加計時代碼。查看圖2.1,您能夠看到,經過衆多列出的API提供的系統時間可讓您精確到數百毫秒,或者比腳本好一個數量級。若是您想得到更精確的信息,您須要使用利用高精度時間源的API,一般稱爲QPC(QueryPerformanceCounter Win32 API的縮寫)。
注意:從歷史上看,當CPU以MHz頻率運行時,系統時間的精度「足夠好」。隨着時鐘速度快得多的CPU的引入,系統時間精度不足以測量更高精度的微活動。雖然您仍然可使用系統時間來測量一些邊緣響應場景(即測量300-500ms的持續時間),可是若是僅依賴系統時間精度,再想將此類場景的持續時間分解爲更細節的基礎子活動就面臨困難。所以,您將看到咱們在本書中大量利用了更精確的QPC時間源。
你說,爲何系統時間和QPC都要測量時間?系統時間表示每一個人都習慣的日曆時間。這使得日誌中的發生時間可以映射到平常人類活動。另外一方面,QPC從系統通電開始計數,而且與日曆時間沒有相關性(儘管您可使用上次引導系統時間來映射QPC時間到日曆時間)。所以,二者都有他們的用途。系統時間爲您提供日曆時間上下文,而QPC時間提供更高精度的測量。
注意:在Windows 8中,經過引入WDK KeQuerySystemTimePrecise()
和Win32 APIGetSystemTimePreciseAsFileTime()
,系統時間的API精度獲得了提升,更多詳細信息,請參閱MSDN。
我的補充:初步看了下MSDN, Win32 API GetSystemTimePreciseAsFileTime
最大的做用是用於高精度測量,且須要關聯繫統時間的場景。
衆所周知,業內許多成熟的代碼庫在其自定義測量中仍然依賴於系統時間。正如咱們稍後將看到的,那些選擇使用ETW的實現能夠在這些時間源之間輕鬆切換,而無需任何代碼更改。
如今咱們已經討論瞭如何測量時間,接下來讓咱們看看Windows附帶的許多性能監控工具,看看如何使用它們來解決咱們在第1章中討論過的問題。
回憶一下咱們在第1章練習1.1中回顧過的性能問題的基本示例。在該練習中,咱們可以定位致使系統運行緩慢的緣由是CpuHoger.exe致使了CPU飽和。爲了收集證據,咱們使用WPR捕獲ETL跟蹤,而後依靠WPA來肯定罪魁禍首進程。
對於由單個進程致使的如此簡單的CPU飽和的場景,實際上還有其餘內置工具(它們與Windows捆綁在一塊兒)能夠定位該場景。讓咱們利用這個機會回顧一下其中的一些。若是您熟悉這些工具及其侷限性,請隨時跳過這些練習
任務管理器隨Windows一塊兒提供,是最經常使用的面向最終用戶的工具,旨在識別和幫助緩解典型的飽和來源(例如,經過終止故障進程或下降其執行優先級緩解系統卡慢)。任務管理器從XP到Windows 7基本上沒有變化,在Windows 8中經歷了至關大的演變。特別是,「性能」選項卡已徹底從新設計,以近乎實時地顯示關鍵系統性能指標(KPI)(即資源使用狀況能夠每秒鐘更新一次)。這些指標包括CPU、內存、存儲和網絡。
在本練習中,咱們將使用Windows 8版本的任務管理器。讓咱們看看當咱們運行CpuHogger.exe時,任務管理器會顯示什麼。
本節介紹如何使用任務管理器定位致使系統卡慢的進程。
打開任務管理器
切換到詳細信息界面
切換到性能標籤頁
運行CpuHogger.exe
咱們能夠觀察到系統變得未響應,當從新能夠響應是你將看到一個相似下圖的凸起。
請注意,在CpuHoger.exe運行時,您沒法與任務管理器交互。一旦CpuHoger.exe中止運行,任務管理器再次變得響應,咱們看到CPU實際上在其無響應的時間間隔內飽和。不幸的是,任務管理器是一個實時監測工具,沒辦法回到過去檢查是哪一個具體進程致使的。你必須在出問題的過程當中找到罪魁禍首。
CpuHoger碰巧使用應用程序可用的最高執行優先級,而任務管理器以默認優先級運行,所以出現問題時它也沒有響應。咱們將在第9章更多地討論執行優先級。目前,請記住,優先級較高的進程比優先級較低的進程得到更多的CPU時間。
經過將任務管理器切換爲以實時優先級運行,咱們可使它以比CpuHoger更高的優先級運行。這將使咱們可以使用其GUI識別罪魁禍首進程。要將任務管理器切換爲實時優先級運行,請右鍵單擊「詳細信息」選項卡中的條目,選擇「設置優先級」,而後選擇「實時」,如圖2.3所示。
如今,咱們已經確保了任務管理器以實時優先級運行,讓咱們來看看誰消耗了最多的CPU時間。爲此,請經過單擊「詳細信息」選項卡中的「CPU」列的標題,按降序排序
如今,讓咱們添加基本優先級列,以查看哪一個進程以什麼優先級執行。爲此,右鍵單擊標題,選擇選擇列,而後選擇基本優先級,如圖2.4所示。
再次運行CpuHogger.exe
您應該看到相似於圖2.5中所示的內容。也就是說,當CpuHoger.exe運行時,它被列在詳細信息列表的頂部,佔用99%的CPU時間。請注意,Taskmgr.exe以實時優先級運行,而CpuHoger.exe以正常優先級運行。這確保了咱們可以與任務管理器交互,即便CpuHoger使CPU飽和。
注意:爲了確保CPU飽和,CpuHoger將其工做線程的優先級提升到最高可用的非實時優先級——即優先級15。當咱們將任務管理器設置爲以實時優先級運行時,它的線程以24到26的優先級運行,這要高得多,使它可以保持響應。線程執行優先級不是您能夠在任務管理器中看到的。在第9章中,咱們將向您展現如何在WPA中查看此信息。
您還能夠經過單擊進程選項卡觀察CpuHoger.exe的高CPU使用率。圖2.6顯示了一個與您將在那裏看到的相似的視圖。請注意,在查看CPU之外的資源飽和時,「進程」選項卡可能頗有用。
在本示例中,咱們已經向您介紹瞭如何使用任務管理器識別致使CPU飽和的罪魁禍首進程。爲了肯定實際進程,咱們必須將任務管理器提高到實時優先級,並在問題發生時捕獲問題。任務管理器不提供記錄工具和離線分析功能,使其有用性僅限於幫助識別持續的CPU飽和問題.
正如咱們剛纔看到的,任務管理器基本上提供了反映系統活動的實時視圖
注意:任務管理器默認使用的1秒1次的正常更新速率,在高更新速率下以0.5秒更新一次,在低更新速率下以4秒更新一次,您能夠查看從30秒(高更新頻率)到4分鐘(低更新頻率)的總CPU使用率的總體趨勢圖。
固然,這裏的關鍵限制是,要查看哪些進程致使了高CPU使用率,咱們須要監控問題發生時正在更新的列表,這並不老是實用的。爲了更好地查看當時發生的事情,咱們可使用另外一個內置工具,稱爲資源監視器。在下面的練習中,咱們將使用該工具對同一問題進行分析。
雖然任務管理器提供了對系統性能的基本描述,但對一個展示關鍵系統資源的活動細節的視圖一般是問題診斷所必需的。爲了知足這一需求,資源監視器已添加到Windows Vista中的操做系統中。雖然此工具從一個版本到另外一個版本一直在發展,但其關鍵功能集在Windows 8中基本上保持不變。
經過任務管理器「性能」選項卡頁下面的按鈕打開資源監視器,或者命令行執行perfmon.exe /res
打開
與任務管理器不一樣,資源監視器保持跟蹤完整1分鐘的CPU活動,所以即便您沒法實時觀察問題,您仍能夠在一分鐘時間窗口內看到問題。
可選:與上一個練習同樣,您可使用任務管理器提升資源監視器的優先級。爲此,請在任務管理器的「詳細信息」選項卡中顯示的進程列表中找到PerfMon.exe,並將其CPU優先級設置爲實時(有關如何執行此操做的示例,請參閱圖2.3)。請注意,查看CPU使用歷史記錄和識別罪魁禍首進程不須要這樣作,但只有當咱們提升資源監視器的優先級時,才能在CpuHoger.exe運行時實時觀察CPU使用峯值。
運行CpuHogger.exe
請注意,系統變得無響應。若是您提升了資源監視器的優先級,您會注意到它將繼續更新本身,由於它的運行優先級高於CpuHogger.exe。若是您沒有,它將顯示掛起,就像任務管理器同樣,直到CpuHoger.exe完成,但隨後將刷新並顯示CPU使用狀況。
在CpuHogger.exe退出後,你應該能夠看到相似圖2.7顯示的狀況:
正如您所看到的,CpuHoger位於列表的頂部,在其生命週期內平均佔總CPU利用率的55%,如「平均CPU」列中所示。這是迄今爲止列表中最高的CPU使用者。
注意: 從資源管理器中看到CPU一列的CpuHoger.exe的CPU使用率爲23%,它表示從上次採集到這次期間的CPU使用率。默認狀況下,資源監視器使用1s採樣頻率。
資源監視器還附帶了用於關鍵系統資源的專用選項卡,包括CPU。在CPU選項卡中觀察CpuHogger.exe時,您將看到與2.8所示相似的內容
請注意,在CPU選項卡中,除了CPU整體使用狀況外,您還能夠查看系統上每一個邏輯核的CPU歷史記錄。因爲CpuHoger.exe使全部可用的邏輯處理器飽和,所以咱們能夠看到系統上全部邏輯處理器的CPU利用率類似。
注意:經過觀察每一個CPU核利用率視圖, 能夠更容易看到爲何CpuHogger.exe的平均使用率大概爲53%。(這裏感受看整體的話,在1分鐘的週期內,確定沒有佔到53%。 那是否是意味着,聯繫到上面的採集週期是1s1次,所以猜想好比這個程序運行15s,那麼在這15s的採樣週期內,CpuHogger.exe大概會佔53%多的CPU時間片,應該數據是由此而來。)
在本示例中,您已經學習瞭如何使用資源監視器識別致使CPU飽和的罪魁禍首進程。與任務管理器不一樣,不須要將資源監視器提高到實時優先級,由於它能夠記錄過去60s的歷史記錄。不過,與任務管理器相似,資源管理器也不提供記錄工具和離線分析功能,它侷限於幫忙分析在程序執行的最近1分鐘內的CPU飽和問題。
正如咱們剛纔看到的,資源監視器提供了一個基本的一分鐘跟蹤視圖,以瞭解系統活動。您可使用另外一個名爲Performance Monitor的內置工具進一步進行此分析。在如下練習中,咱們將使用性能監視器分析同一問題。
雖然任務管理器和資源監視器提供了對系統性能的基本觀察看法,但在分析已經發生的事情時,您一般不想倉促行事。事實上,在許多狀況下,你甚至不在那裏實時看到它。固然,有時您也沒有對有關計算機的物理(甚至遠程)訪問權限。顯然,離線性能分析的須要可能相當重要。要實現離線性能分析,咱們須要可以以性能跟蹤(例如日誌)的形式收集證據。
實際上,當咱們捕獲ETL文件時,咱們已經在練習1.1中成功地收集了一個這樣的Trace。此性能跟蹤日誌幫助咱們診斷CpuHoger.exe的CPU飽和問題。正如咱們以前提到的,Windows附帶了兩個互補的檢測平臺,形式是Windows性能計數器(PCW)和Windows事件跟蹤(ETW)。當咱們在第1章的練習1.1中捕獲ETL跟蹤時,咱們使用ETW平臺進行性能測量。如今,咱們來回顧一下如何利用PCW來診斷該問題。
早在Windows 95, Windows就與一個專門用於性能監控的工具捆綁在一塊兒。該工具最初稱爲系統監視器(SysMon.exe),在Windows 2000中被從新命名爲性能監視器(PerfMon.exe)。它構建在PCW之上,容許您跟蹤特定性能計數器(如CPU和磁盤利用率)隨時間推移的值。在過去幾十年裏,多個應用程序、服務和驅動程序也提供了本身的性能計數器。PerfMon如今一般用於在大時間跨度內監控系統的性能。
默認狀況下,性能監視器近乎實時地跟蹤當前活動。具體來講,您能夠看到您選擇監控的PCW計數器的最近100秒的數據。這與咱們在任務管理器和資源監視器中看到的視圖類似。在下面的練習中,讓咱們嘗試將此監控功能用做CPU飽和診斷工具。
本節介紹用於使用Performance Monitor的當前活動視圖肯定致使系統上出現卡慢的罪魁禍首進程的分析工做流程。
開始菜單打開性能監視器
打開性能監視器圖表工具,如圖2.9所示
請注意,此視圖顯示了隨時間推移的總處理器利用率。在近乎實時的觀察模式下運行時,PerfMon會顯示選定性能計數器的100秒後的值。默認狀況下,已選擇%Processor Time
,會默認展現CPU時間趨勢
注意:與任務管理器和資源監視器不一樣,它們在顯示圖形信息時利用視圖平移,性能監視器在顯示新數據時循環覆蓋之前的數據
如今,讓咱們經過運行CpuHoger.exe來重現性能問題。在應用程序完成其邪惡行爲後,您將看到一個相似於圖2.10所示的視圖。
咱們如今知道CPU已經飽和,但咱們還不知道是哪一個進程形成的。要找出答案,讓咱們嘗試使用「每一個-進程「性能計數器。
點擊添加按鈕或者快捷鍵Ctrl+Shift+N
,打開相似2.11所示界面:
此視圖顯示系統上全部可用的性能計數器,按性能計數器組分組。要開始顯示實際計數器隨時間推移的值,您須要將該計數器的實例添加到右側列表框中。
找到Process
選項卡,只選擇% Processor Time
觀察進程的CPU時間,而後在下面的框中選擇全部進程,而後添加。
略,包含在8步裏了
因爲實例是按字母順序列出的,CpuHoger應出如今conhost#2和csisyn~1之間。可是,正如您可能注意到的,CpuHoger.exe沒有列出在那裏,如圖2.12所示。這並不奇怪,由於咱們尚未啓動它。、
添加全部實例。
單擊肯定,而後運行CpuHoger.exe。您最終看到的內容將與圖2.14中所示的視圖類似。請注意,咱們能夠選擇加號右邊的右邊的畫筆按鈕突出顯示選定的數據行,重點關注處理器的總使用狀況。
請注意,總處理器使用率如預期的那樣上升,但沒有特定進程的CPU使用率隨之上升。事實上,您能夠看到,在7:12:38PM和7:12:58PM期間,其餘進程的CPU使用率下降了。只有當總CPU使用率從100%開始降低時,咱們纔會看到其中一些進程以持續到晚上7:13:05的突發形式恢復其CPU使用率模式。
注意:正如咱們稍後將瞭解的那樣,這被稱爲CPU匱乏,CpuHoger.exe阻止了全部其餘活動取得應有的進展。
注意:此限制僅存在於PerfMon的實時監控功能。正如咱們稍後將看到的,它不會影響PCW跟蹤到BLG文件。
在本示例中,咱們試圖使用性能監視器識別致使CPU飽和的罪魁禍首進程,但再次遇到了工具的限制。具體來講,咱們不能使用性能監視器的實時觀察視圖,由於它沒法監視在監視開始後才運行的進程。
性能監視器已經存在了近20年(截至本書撰寫時),性能計數器生態系統很是活躍。雖然自Windows 2000以來,PerfMon的UI沒有進行重大投資,但該工具仍在許多服務器監控場景中普遍使用。若是您想了解更多關於PerfMon的信息,您只須要在線搜索。
在上一個練習中,咱們嘗試經過PerfMon的實時監控功能使用PCW診斷CpuHoger.exe致使的CPU飽和。不幸的是,咱們沒有成功,由於PerfMon的當前活動視圖不跟蹤新啓動的進程。可是,有一種能夠利用PCW平臺的方法來診斷此問題,即便用PerfMon的離線分析功能,以BLG(Binary Log :二進制日誌)跟蹤的形式。
本節介紹了收集數據所需的數據收集工做流,而後咱們將使用這些數據來肯定致使您在系統上經歷的卡慢的緣由。
啓動性能監視器
展開左側的數據收集器集(Data Collector Set)項目,而後右鍵單擊用戶定義(User Defined)項目,而後單擊新建|數據收集器集選項,如圖2.15所示。
讓咱們將此數據收集器集稱爲「CPU使用率」,選擇手動建立(高級),如圖2.16所示,而後單擊下一步
下一步選擇性能計數器, 繼續點擊下一步, 如圖2.17
在下一頁上,單擊添加...添加如下三個計數器,添加的過程和上一個練習中描述的過程相似:
\Process(*)\% Processor Time \Processor(_Total)\% Processor Time \Processor Information(_Total)\% Processor Utility
完成後,將採樣間隔設置爲一秒。完成後,您應該看到一個相似於圖2.18所示的視圖。
後面只需單擊「完成」做爲下一步。而後,您應該看到在用戶定義文件夾下建立的CPU使用量數據收集器集,如圖2.19所示。請注意,在左側的「報告」節點下還建立了用戶定義的\CPU使用狀況報告文件夾。一旦咱們收集了測量報告,咱們就會在這裏找到報告。
右鍵單擊CPU佔用率,而後選擇Start,啓動新建立的數據收集器集,如圖2.20所示。
在收集的過程當中,運行CpuHogger.exe
請注意,系統再次變得無響應,但這應該再也不是一個問題,由於咱們如今正在後臺記錄系統活動。
注意:正如您將看到的,因爲CpuHogger.exe的自大狂性質,它可能從PerfMon的數據收集中竊取CPU時間片,所以您可能仍然會丟失一些數據,
CpuHogger.exe
退出後,再次右鍵CPU使用率數據收集器並點擊中止展開報告\用戶定義下的CPU使用率文件夾以查找新生成的報告。雖然您的視圖將有所不一樣,但您仍然可能在測量中看到間隙,整體使用率相似於圖2.21所示。
如今,讓咱們添加每一個進程%Processor Time計數器的All instances,以嘗試查找違規進程。您會注意到,添加它們雖然仍然存在部分時間段沒法看到數據的問題,如圖2.22所示,但您能夠看到CpuHoger.exe確實列在這些進程中,而且它在成功獲取數據的時間範圍內消耗了100%的CPU,如預期的那樣(在100的頂部的一條小橫線,圖上不太好看)。
形成這些差距的緣由是PCW是一個輪詢基礎架構,其中輪詢代碼在用戶模式下運行(應咱們的請求啓動以收集測量數據)。此執行以正常優先級進行。因爲CpuHoger.exe以更高的優先級運行,它能夠阻止PerfMon的數據收集取得進展。前面咱們嘗試使用任務管理器和資源監視器時,咱們已經遇到了這個問題。
不幸的是,在這種狀況下,提升PerfMon UI應用程序(託管在mmc.exe中)的優先級並不能解決問題。實際上,計數器輪詢發生在不一樣的進程(rundll32.exe)中,該進程爲每一個數據收集器集運行單獨啓動。
要使用「手動優先級提高」方法消除測量中的差距,咱們必須先開始數據收集,在任務管理器中找到用於數據收集的rundll32.exe的特定實例,而後將其優先級提高到實時。然而,有多個rundll32.exe實例的狀況並不罕見。找到對的進程多是一個挑戰,並且在實踐中咱們並不建議這樣作。
若是咱們真的這樣作了,Gap就會消失,如圖2.23所示。雖然您能夠嘗試確認這一點,但咱們實際上不建議將「手動優先級提高」做爲性能衡量方法。特別是,經過將進程提高到高優先級,您可能會影響你試圖測量的場景。咱們這麼嘗試只是爲了更好地理解基於PCW的數據收集的侷限性
注意:PCW從用戶模式進程中採樣,所以很容易受到CpuHoger等自大狂進程的影響。與PCW不一樣,ETW從系統自身內部收集數據,不受此類問題的影響。在下一節中,咱們將更仔細地瞭解切換到ETW進行性能測量的好處。
在本示例中,咱們再次嘗試使用性能監視器識別致使CPU飽和的罪魁禍首進程。咱們沒有使用其實時界面,而是依賴其對使用用戶定義的Data收集器集捕獲的BLG文件的離線分析,這使咱們可以跟蹤新啓動的進程(包括CpuHoger.exe)的性能計數器。請記住,經過近乎實時的監控,咱們沒法跟蹤新啓動的進程
不幸的是,咱們再次遇到了以正常優先級收集數據的限制,即它被CpuHogger.exe這種更高優先級的問題進程搶佔了時間片。這致使了在咱們須要的時候,咱們的測量出現了誤差。然而,咱們仍然能夠瞥見CpuHoger.exe貢獻的高CPU使用率。 而且經過提升基礎收集進程的優先級(咱們不建議您實際中這樣作)來確認這一點。
數據收集器集能夠成爲性能監控的強大盟友。它容許您定義特定的PCW測量,並按需或特定時間表收集它們(您能夠在文檔或在線中閱讀這一功能)。事實上,數據收集器集甚至容許您收集ETW測量值,或PCW和ETW的組合。請注意,生成的ETL跟蹤在性能分析中不如WPR捕獲的跟蹤有用,由於它們缺乏了許多關鍵的元數據。所以,在本書中,咱們將重點討論使用WPR捕獲的跟蹤。
注意:數據收集器集也可使用LogMan.exe內置程序從命令行管理,以及使用Performance Logs And Alerts:性能日誌和告警(PLA)經過Win32 API以編程方式管理。
注意:收集BLG文件的另外一種快速方法是使用內置TypePerf程序。例如,要捕獲每一個進程CPU使用率,咱們可使用如下命令:typeperf "\Process(*)\% Processor Time" -f BIN -o PerProcessCpuUsage.blg
。好消息是,使用TypePerf,您能夠知道應該提高哪一個進程的優先級(即typeperf.exe進程自己)。
Performance Monitor還附帶了報告生成功能,若是您在建立新的用戶定義的數據收集器集時使用默認建議模板,您就能夠得到這些功能。或者,您也能夠只使用性能監視器附帶的系統\系統性能數據收集器集。
注意:內置數據收集器集配置爲僅捕獲60秒的測量
雖然這些功能在穩態負載下對服務器系統進行容量測量很是有用,但這些報告一般不包含對性能問題執行有效根本緣由分析所需的數據。
正如咱們在上一節中所看到的,咱們嘗試過的用於診斷CPU飽和的每個工具都有其缺點,任務管理器要求咱們實時捕獲問題。資源監視器確實給了咱們一分鐘的窗口,這要歸功於它的尾隨平均值,但沒有提供離線分析功能。接下來,咱們查看了性能監視器,若是使用正確,它容許咱們使用BLG文件進行離線分析,這些文件確實指向消耗系統上大部分CPU的進程。正如咱們所看到的,對於某些類型的性能問題,PCW能夠成爲根本緣由分析的有效工具。話雖如此,它的有效性受到各類限制,咱們稍後會繼續討論。
注意:咱們所回顧的內容提供了一個至關完整的內置工具清單,以及大多數Windows套件中包含的推薦工具。與大多數工具生態系統同樣,您還可使用其餘性能工具。其中一組值得明確調用的工具是SysInternal工具。在這個工具包中,您能夠找到一個很是強大的工具,稱爲Process Explorer,提供了任務管理器和資源監視器提供的大部分功能,並且還有許多改進。有關更多詳細信息,請訪問http://www.sysinternals.com
回到第1章,在練習1.1中,咱們已經看到了如何在WPR和WPA的幫助下使用ETW技術診斷相同的問題。PCW和ETW兩種不一樣的技術,都支持使用性能跟蹤(BLG for PCW,ETL for ETW)的離線分析,咱們應該何時使用哪一種技術?讓咱們在下一節中探討這些測量和分析平臺的利弊
回顧第1章,Windows中有兩個可用於收集性能測量的替代平臺:Windows性能計數器(PCW)和Windows事件跟蹤(ETW)。
性能計數器使您可以採樣反映系統當前狀態的各類數據點。經過按期查詢這樣的計數器,您能夠得到系統狀態隨時間變化的視圖。例如,運行進程數的計數器將反映查詢計數器時正在運行的進程數。若是您每隔一秒鐘查詢此計數器,您能夠繪製一個趨勢線圖,以顯示系統上運行的進程數隨時間的變化趨勢。
與性能計數器不一樣,性能計數器只能包含按期採樣的數字數據,ETW事件由事件提供程序(Event Providers)(負責記錄ETW事件的邏輯實體)在特定操做或狀態轉換髮生時的確切時刻進行記錄,而且包含豐富的數據。支持普遍的數據類型,包括字符串、結構化數據集、時間戳、GUID等。也與只能採樣的計數器不一樣,ETW跟蹤事件能夠在狀態更改發生時進行記錄(即它們遵循推送模型(push model))。回到咱們以前的監控系統上運行進程數量的示例,使用ETW的話,每次建立或終止進程時,您都會收到事件。從這些數據中,人們不只能夠得到在任何給定時間點在系統上運行的進程數量,並且還能夠訪問更豐富的信息,包括進程名稱、確切的建立和終止時間戳、相應的命令行等等。
上面列出的兩種機制是在Windows上收集性能信息的標準方法。它們都附帶了對應的一組豐富的日誌記錄和處理的API,以及一組匹配的命令行和基於UI的工具,用於收集和分析數據。
PCW早在ETW以前就出現了(早在Windows 95以前)。它的主要目的是支持從Windows中的系統組件按需收集性能指標。爲了處理大量數據,在內存稀缺、磁盤速度慢的時代,每次感興趣的指標在更改其值時記錄事件是不可行的。所以,這些度量將由其本身的組件聚合,一般以自定義的方式聚合。這爲那個時代創造了一個足夠好的監控平臺,且該平臺至今仍在使用——這主要是因爲生態系統中衆多產品對性能計數器的大量投資。
ETW是在Windows性能團隊中Windows 2000建立的,但直到在Windows Vista發佈後,針對瞭解和優化windows性能纔有了很大的推進力,此時ETW才全面發揮了做用。它提供了對系統活動的更深刻的視圖,包括單個操做的級別,以及啓動這些操做的代碼。
從Windows 7開始,許多系統組件開始切換到ETW進行根因分析。在許多狀況下,這提供了必定程度的維測功能,而之前,若是不首先重現問題,確定沒法定位到根因。讓咱們經過檢查這兩個平臺之間的主要差別來回顧是什麼讓他們實現了飛躍。
下表展現了代碼開發方面的對比。
領域 | PCW | ETW |
---|---|---|
添加檢測 | 簡單(對於支持實時聚合的數據) 中等(對於不支持實時聚合的數據) |
簡單(僅日誌事件) |
語言支持 | 普遍的(c/c++, .NET) | 普遍的(c/c++, .NET, JScript) |
下表展現了根因分析對比
類別 | PCW | ETW |
---|---|---|
活動 | 聚合的(累計值不斷記錄日誌) | 離散的(支持深刻分析) |
根因分析 | 必定程度受限 | 支持分析到代碼 |
關於數據收集
類別 | PCW | ETW |
---|---|---|
主要預期功能 | 監控 | 調試 |
時間尺度 | 秒級~天級 | 毫秒級~分鐘級(服務於性能分析) |
從發生到記錄的時間戳的延遲 | 顯著的(受限於計數器實現精度、計數器獲取數據的損耗) | 很是接近實際發生時間(毫秒級) |
日誌格式 | BLG | ETL |
執行優先級 | 用戶態程序(可被高優先級活動搶佔) | 系統優先級(不會被搶佔) |
DBMS集成 | 支持 | 不支持 |
內容 | 有限的(數字) | 普遍的(數字、字符串、結構、數組、碼流) |
開始採集後發生的瞬態活動可否監控到 | 支持(PerfMon不支持) | 支持 |
函數調用棧 | 不支持 | 支持 |
文件名 | 不支持 | 支持 |
活動跟蹤 | 不支持 | 支持 |
跟蹤便攜性 | 簡單 | 簡單(經過WPR和xperf) |
遠程收集 | 簡單 | 困難 |
計量清單 | 簡單(在PerfMon中經過列舉「Providers」和指定的性能計數器) | 中等(能列舉providers,但不是具體事件) |
工具 | GUI(PerfMon數據收集器)、CMD(LogMan、TypePerf) | GUI(WPRUI)、CMD(WPR、Xperf、TraceLog、LogMan) |
關於性能分析
類別 | PCW | ETW |
---|---|---|
離線分析 | 支持 | 支持 |
接近實時監控 | 支持 | 不支持(理論上可行,可是沒有工具) |
非聚合數據分析 | 不支持(只有累計值) | 支持(單個事件) |
分析時間的聚合 | 困難(經過計數器暴露,一般沒法導出) | 簡單(只要工具支持就OK) |
程序化測量模式發現 | PDH Win32 API | TDH Win32 API |
關於工具
PCW | GUI | CMD | ETW | GUI | CMD |
---|---|---|---|---|---|
離線 | PerfMon | TraceRpt,TypePerf | 離線 | WPA | xperf,TraceRpt,WpaExporter |
在線 | 任務管理器,性能監視器,資源監視器 | TracerRpt | 在線 | 資源監視器(其中某些指標) |
表2.1至表2.4中列出的ETW的優點包括可以專一於亞秒級活動,以高精度將它們放置在時間軸上,以及可以獲取調用堆棧和捕獲非數字數據類型。這些優點使ETW成爲典型性能問題根因分析的首選。
另外一個值得記住的好處是,ETW基於事件的推送模型提供了更靈活的日誌記錄方法。您能夠始終改進脫機分析功能,但一旦提供了性能計數器,那就是你在該版本中得到的全部。例如,內置性能計數器可能爲給定度量值提供最小值、平均值和最大值,但它可能缺乏90%分位數。若是你決定在代碼成熟時關心95%和99%的百分位呢?更別提PCW將提供的任何統計信息都硬編碼到特定的時間間隔。爲了在分析中得到真正的靈活性,咱們顯然須要將數據聚合推遲到實際分析,而不是嘗試預測咱們在運行時須要什麼數據。
這並非說PCW應該被忽視。雖然缺少一些列出的領域,但它仍然提供了足夠的價值,使咱們在性能工程方面獲益。因爲本書的重點是診斷,所以對PCW技術的詳細描述不在本書的範圍以內。不過,咱們將在整本書中酌情提到PCW,以適用於其優點能夠有效應用的場景。
注意:請記住,性能工程能夠側重於提升響應性和/或效率。考慮如下示例,其中PCW和ETW用於實現這些目標:
交互響應能力
測量時彙總:PCW –例如最小、最大和平均響應延遲
分析時彙總: ETW -例如每一個交互的開始/中止事件
效率: 資源使用率
測量時彙總: PCW --例如處理器用途、磁盤時間
好工具
遠程收集
告警
DBMS集成
大時間跨度
缺少調用堆棧可見性,沒法將資源使用狀況與相應的消費者和活動聯繫起來
分析時彙總: ETW--例如磁盤IO的啓停,上下文切換、CPU採樣事件
PCW和ETW的互補優點使它們成爲兩種共生類型的性能反饋系統的良好候選者,咱們將在下一節中回顧這些系統。
在大多數對跟蹤和提升產品性能感興趣的組織中,出現了兩個互補的流程:
監控--持續(即7*24小時)跟蹤關鍵業績指標,目標是:
確保監測指標達到和/或超過目標響應性、流動性和/或效率目標(性能目標)
在適當的優先級和嚴重程度上出現目標違反和迴歸事件
診斷--按需(例如及時、基於觸發、基於升級等)對關鍵系統和用戶活動進行測量,目標是對經過監控出現的問題進行根本緣由分析。
監控一般涉及跟蹤較長的時間段(跨越小時的時間段)。監控一般側重於低頻活動(例如1Hz如下),持續時間爲一分鐘或更長。示例包括
聚合吞吐量(例如每分鐘平均/峯值操做)
每分鐘平均使用率(例如CPU使用率、磁盤使用率)
收集的數據一般足夠小,能夠以業務可接受的成本保留數週甚至數月的數據,從而瞭解質量從一天到一天、一週到一週、月到月、發佈到發佈的趨勢。
另外一方面,當問題浮出水面時,診斷就會發揮做用——一般是一個須要快速有效補救的高几率問題。這些問題能夠經過測試(合成工做負載)或監控(遙測)主動地浮出水面,甚至能夠由最終用戶被動地浮出水面。考慮到診斷大多數性能問題須要大量數據,所以須要收集更多數據才能成功進行根本緣由分析。
爲診斷收集的數據一般跨越幾分鐘,在此期間跟蹤高頻活動(遠高於1KHz)。此類活動一般具備亞秒級的持續時間(例如,單個磁盤I/O)。鑑於收集的測量結果的豐富性,由此產生的數據量多是巨大的。所以,長時間保留它們可能至關昂貴,須要實施謹慎的保留策略,以免沒必要要的資源浪費
注意:限制診斷測量期間收集的數據量的一個常見緩解措施是依賴循環日誌記錄技術,在這種技術中,特定大小的緩衝區以循環方式預先分配和覆蓋。這樣,僅保留最新的測量值(未覆蓋)。
注意:在評估監控和診斷反饋系統的效率時,有幾個關鍵指標。具體來講,檢測時間(time to detection,簡稱TTD)是有效監控的關鍵指標,而致使時間(time to cause,簡稱TTC)和補救時間(time to remediation, 簡稱TTR)是有效診斷的關鍵指標。這兩個反饋系統的一個共同指標是緩解時間(time to mitigation, 簡稱TTM)。典型的時間線是TTD→TTC→TTM→TTR,即您檢測到,而後是根本緣由,而後是緩解,而後是根因(譯者注:這裏應該是補救吧?)。請注意,有些問題能夠在沒有根本緣由的狀況下緩解,但要補救問題,您必須首先肯定根本緣由。
咱們已經提到,監控一般是經過PCW實施的。這是否意味着ETW作了一個糟糕的平臺來實現監控?一點也不。您可使用PCW構建的任何反饋系統也能夠構建在ETW之上(請注意,狀況並不是如此)。事實上,ETW的結果可能會更有效。不過,PCW更早出現,在PCW之上構建的全部衆多性能監控工具也是如此,包括與數據庫的集成,這些工具提供了在監控領域的豐富的商業智能可能性——尤爲是在服務器端。有許多性能指標能夠經過PCW有效監控,並提供足夠的工具支持。
然而,在這本書中,咱們主要關注有效診斷的方法論,只是順便提到監控反饋系統。在性能領域,市場上存在多種監控方法。討論這些問題超出了本書的範圍。
收集性能數據有一些補充辦法。讓咱們在本節中回顧一下它們。
正如咱們剛纔在PCW與ETW的討論中看到的,從概念上講,收集性能數據有兩種方法。具體來講,數據收集能夠遵循拉式模型,也能夠遵循推式模型。在拉取模型中,數據會按期查詢,而在推送模型中,每次發生狀態轉換時都會記錄數據。收集的數據能夠是瞬時的(例如當前溫度),也能夠是累積的(例如整個拖後時間段的平均溫度)。
注:表2.5說明了推拉數據收集模型的幾個示例,描述了當與表示時間點的即時值或在時間間隔內聚合的累積測量一塊兒使用時的場景:
數據 | 推式 | 拉式 |
---|---|---|
瞬時值(時間點) | 上下文切換和磁盤IO ETW檢測 | CPU採樣分析、採樣進程工做集ETW檢測、一些PCW計數器(例如處理器駐留狀態) |
累積值 | 緊湊型上下文切換(譯:沒看懂)ETW檢測 | 大多數PCW計數器(例如CPU利用率) |
推拉模式都有其優缺點。相似地,瞬時值和累積值在實際性能工程應用中都有用途
在性能分析的上下文中查看拉式和推式模型的另外一種有趣的方法是考慮性能數據是如何生成的。存在兩種主要方法:
採樣(Sampling)是週期性或偶發狀態集合,後來被用於經過近似統計來度量活動
歸因(Attribution)是經過精確的事件劃定特定的活動,後來被用於精確統計確切發生的事件來度量活動
譯者注: 沒咋看懂
請注意,採樣是拉取模型的示例(數據在採樣發生時拉取),而歸因是推取模型的示例(數據在事件發生時推出)。
把這些新術語應用到PCW和ETW的角度來看的話,PCW數據在徹底由消費者定義的時間表上經過輪詢進行採樣獲得,PCW的數據匯聚在生產者端,它低頻監控用戶定義的數據。相反,ETW數據經過生產者在事件發生時推送事件獲得,數據的聚合在消費者這端,ETW提供對診斷中一般必要的高頻數據的訪問(歸因)。
按期提取數據的行爲一般被稱爲輪詢。正如咱們將在第7章中看到的,基於輪詢的性能數據收集的一個示例是基於樣本的CPU分析,其中CPU使用狀況(默認狀況下)每毫秒採樣一次。
注意:具體來講,CPU採樣分析的工做原理是按期查詢處理器指令指針位置並將其映射回代碼。使用這些採樣數據,人們能夠從新建立一個至關準確的圖片,說明在程序中的時間花費。
採樣的一個顯著優勢是,它不須要對正在運行的程序代碼進行任何修改,並且一般不會過於侵入性。與採樣不一樣,歸因須要修改代碼,並涉及從新啓動正在診斷的程序。
注意:程序中的自定義活動的歸因須要對相應的程序進行更改。操做系統活動(如上下文切換和磁盤I/O)的歸屬可在任什麼時候間點按需提供,由於這些活動已經在Windows中進行了檢測
歸因的一個顯著優勢是它提供了高精度的測量。另外一方面,經過抽樣得到的數據本質上是不顯眼的,它可能會忽略其兩個相鄰樣本之間發生的活動。另外一方面,歸因只捕獲狀態轉換,而且可能會錯過在這些轉換之間發生的活動,而採樣一般仍然能夠得到足夠好的近似值。咱們將在第7章中使用CPU做爲案例研究,對比這兩種互補的測量方法。
請注意,歸因可能會致使生成比採樣更多的性能數據。在抽樣的狀況下,數據量與抽樣率成正比,而在歸因的狀況下,數據量與歸屬活動的數量成正比。
來回顧下咱們迄今所學到的內容,Windows提供了幾種用於性能監視和診斷的內置工具:任務管理器、資源監視器和性能監視器。對於CPU佔用率分析來說:
記錄過去60秒的資源活動
與任務管理器相似,不提供記錄工具和離線分析功能,使其用途僅限於幫助在執行的最後一分鐘內識別持續的飽和問題
比任務管理器提供更多的系統活動可視性
與任務管理器和資源監視器不一樣,支持經過使用用戶定義的數據收集器集捕獲的BLG文件進行離線分析
容許在離線分析中跟蹤新啓動的進程
在近乎實時的可視化分析中,僅顯示在PerfMon以前啓動的進程的活動
Windows提供了兩個用於記錄和收集性能數據的互補基礎設施:PCW和ETW。這兩個平臺已經發展到分別涵蓋監控和診斷反饋系統。
這兩個平臺均可以有效地分析某些類型的性能問題的根本緣由,但ETW在大多數狀況下在診斷方面佔上風。PCW在大多數監測狀況下仍然能夠很是有效。 因爲這本書主要涉及教您如何診斷性能問題,咱們將把大部分注意力都花在ETW上。正如咱們提到的,ETW比PCW提供了更多的分析靈活性,特別是當您須要對收集的數據執行非平凡分析時。在下一章中,咱們將向您展現如何在Windows上使用WPR進行基於ETW的性能測量。