• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎(chǔ)} {C++ 高級} {C#界面,C++核心算法} {設(shè)計模式} {C#基礎(chǔ)}

            Make Your Apps Fly with the New Enterprise Performance Tool (通過新的 Enterprise Performance Tool 使應(yīng)用程序飛速運行)(包含各種排序算法的實現(xiàn))

            http://msdn.microsoft.com/msdnmag/issues/04/12/EnterprisePerformance/default.aspx#contents


            中文:http://www.microsoft.com/china/MSDN/library/enterprisedevelopment/softwaredev/enterpriseperformance.mspx?mfr=true


            發(fā)布日期: 1/6/2005 | 更新日期: 1/6/2005

            John Robbins

            本文基于 Visual Studio 2005 的預(yù)發(fā)布版本。文中包含的所有信息均有可能變更。

            本文討論:

            ?

            分析器的內(nèi)部工作方式

            ?

            EPT 的靈活功能

            ?

            一個供分析的示例應(yīng)用程序

            代碼可從以下位置下載:
            EnterprisePerformance.exe (258KB)

            快速代碼仍然很受歡迎。即使我用來鍵入本文的計算機(jī)具有足夠的能力和內(nèi)存,能夠同時控制一座原子能發(fā)電廠、一個火星漫游計劃以及美國西部上空的空中交通,并且仍然具有充足的能力來處理星際探索中的 SETI 數(shù)據(jù)包,但這并不意味著開發(fā)人員不再需要擔(dān)心其代碼的速度和效率。在過去進(jìn)行 Win32? 本機(jī)開發(fā)的日子里,我們不僅需要擔(dān)心速度,而且還要擔(dān)心 PC 平臺上那些令人討厭的訪問沖突(對于你們這些老家伙,還有“全局保護(hù)錯誤”和“不可恢復(fù)的應(yīng)用程序錯誤”)。盡管托管代碼已經(jīng)消除了其中的一些擔(dān)心,但它只意味著您所經(jīng)歷的那些性能問題可能比以前更加難以捉摸。主要原因是,在使用托管代碼時,我們不具有在進(jìn)行本機(jī)開發(fā)時所擁有的簡便的運行庫視圖。

            有許多次,當(dāng)我正在使用客戶端時,我不知道如何解決惡性的性能問題。當(dāng)然,這些性能問題不會出現(xiàn)在任何測試系統(tǒng)中;它們只會出現(xiàn)在真實世界的生產(chǎn)中。由于公共語言運行庫 (CLR) 是黑盒,因此如果我希望找到在測試系統(tǒng)中重復(fù)性能問題的方法,則很難預(yù)測會發(fā)生什么事情。盡管在市場中有一些第三方商業(yè)性能工具,但這些工具中的大多數(shù)都會對系統(tǒng)造成過多的干擾,以至于根本不能考慮在生產(chǎn)系統(tǒng)中使用。這也就是當(dāng)我看到 Microsoft 將提供一個全新的分析器 — Enterprise Performance Tool (EPT) 以作為 Visual Studio? 2005 Team Developer Edition 的一部分時,感到如此興奮的原因。它是我可以真正考慮在生產(chǎn)系統(tǒng)中使用的第一個分析系統(tǒng),因為它提供了一些非常輕便的收集性能數(shù)據(jù)的手段。因為我曾經(jīng)領(lǐng)導(dǎo)過一種最暢銷的商業(yè)分析器的開發(fā)工作,所以我能夠理解在不產(chǎn)生太多系統(tǒng)開銷的情況下收集有用分析數(shù)據(jù)的困難程度。

            在本文中,我將介紹 EPT 的基本原理,并向您說明如何開始使用它。因為分析器所具有的復(fù)雜性,所以在將來某一期中,我將討論如何使用 EPT 來跟蹤您可能在同事的代碼中遇到的實際性能問題(我知道您的代碼非常完美!)。請記住,EPT 正處在測試階段(我使用的是 Burton Beta 1 刷新位版本 40607.83),并且在該產(chǎn)品發(fā)布之前,可能會對 UI 或某些特定步驟進(jìn)行更改。在對 EPT 進(jìn)行介紹之前,我希望花點兒時間談?wù)撘幌路治銎魍ǔJ侨绾喂ぷ鞯模员隳梢愿玫亓私馐鞘裁词?Enterprise Performance Tool 變得如此與眾不同。


            分析器的基本原理

            在您編寫分析器時,可以選擇兩種收集數(shù)據(jù)的方式中的一種:探測和采樣。這兩種方式都十分有效,但是每種方式都有它的折衷方案。探測分析器收集數(shù)據(jù)的方式是在應(yīng)用程序中插入探測或掛鉤,以便在程序執(zhí)行該掛鉤時就調(diào)用分析器運行庫。要放置探測,分析器需要在編譯步驟中將應(yīng)用程序儀表化,重寫已經(jīng)編譯的二進(jìn)制文件,或者即時將應(yīng)用程序儀表化。要查看基于 .NET 的應(yīng)用程序的探測分析器方法示例,請閱讀 Aleksandr Mikunov 的一篇非常出色的文章 —“Rewrite MSIL Code On the Fly with the .NET Framework Profiling API”(該文章摘自 MSDN?Magazine 2003 年 9 月刊)。當(dāng)我開始討論 EPT 的時候,您將看到它使用術(shù)語“儀表化”來表示探測方法。

            探測分析器方法的主要優(yōu)勢在于,當(dāng)應(yīng)用程序執(zhí)行時,將始終調(diào)用所插入的探測。這樣,分析器運行庫將對運行具有完整的認(rèn)識,因此在生成關(guān)鍵信息(例如,函數(shù)之間的父子關(guān)系)時可以確保正確,并且分析器可以報告完美的調(diào)用樹,以便您可以輕松找到花費最長時間的調(diào)用路徑。使用探測分析器時,沒有什么事情能夠阻止開發(fā)人員只在函數(shù)入口和出口處插入探測。可以在源代碼行級別放置額外的探測,以便您對函數(shù)具有完整的認(rèn)識。

            但是,探測分析器所提供的詳細(xì)視圖具有一些缺點。第一個缺點是儀表化方案使用起來可能很麻煩,并且因為它是在二進(jìn)制級別重寫,因此存在很多可能引入潛在錯誤的領(lǐng)域。正如您可以想像到的那樣,這些探測還占用了空間,從而導(dǎo)致一些代碼膨脹和較低的性能。對于完全儀表化的應(yīng)用程序,探測分析器可能會導(dǎo)致速度大幅度下降,以至于幾乎不可能在生產(chǎn)系統(tǒng)上運行儀表化的二進(jìn)制文件,從而使您在最需要該分析器的時候卻無法利用它。

            正如其名稱所暗示的那樣,采樣分析器按照預(yù)先定義的時間間隔獲得應(yīng)用程序中正在執(zhí)行的操作的快照。大多數(shù)開發(fā)人員都沒有意識到 Microsoft 總是在他們的開發(fā)環(huán)境中隨附了一個采樣分析器。它被稱為調(diào)試器! 如果您開始調(diào)試應(yīng)用程序,并且每隔 30 秒左右就中斷至調(diào)試器,則您可以注意到應(yīng)用程序線程正在何處執(zhí)行,以便很好地了解應(yīng)用程序在一次運行過程中執(zhí)行了哪些操作。我已經(jīng)通過手動完成采樣分析器的工作,解決了很多生產(chǎn)性能問題。

            使采樣分析器如此有價值的原因在于,它們具有比探測分析器小得多的系統(tǒng)開銷。這意味著,您可以有更高的機(jī)會在生產(chǎn)系統(tǒng)中使用它們,而不會使服務(wù)器疲于奔命以至于停機(jī)。采樣分析器的問題在于,從應(yīng)用程序中獲得的所有樣本很有可能根本不顯示任何代碼。例如,如果您具有大量使用數(shù)據(jù)庫的應(yīng)用程序,則所有樣本都可以來自數(shù)據(jù)庫訪問程序集的內(nèi)部。最后,只抓取每個線程的當(dāng)前執(zhí)行指令的傳統(tǒng)采樣分析器會使得確定方法之間的父子關(guān)系變得十分困難,因而確定性能最差的執(zhí)行代碼途徑要困難得多。


            Enterprise Performance Tool 的基本原理

            在了解分析器的操作方式之后,我就可以討論 EPT 所采取的方式了。簡單地說:它既是采樣分析器,又是探測分析器(Microsoft 稱之為“儀表化”)。其思想是,您在開始時將通過采樣分析器來查看應(yīng)用程序性能,以獲得常規(guī)性能特征,以便您可以開始將注意力集中于應(yīng)用程序的熱點問題上。在您了解具有一些問題的程序集之后,就可以求助于儀表化分析以查看特定的問題領(lǐng)域,以便修復(fù)它們。當(dāng)然,如果您要執(zhí)行單元性能測試,則沒有什么能夠阻止您直接轉(zhuǎn)到對特定模塊進(jìn)行儀表化,以便在聚焦方案中查看它們的性能。

            使 EPT 采樣分析器有趣的部分原因在于,您可以使用大量項目來觸發(fā)樣本。默認(rèn)的采樣點是時鐘周期,并且可能是您總是使用的采樣點。默認(rèn)情況下,每一百萬個時鐘周期采樣一次,但是您可以將采樣間隔的時鐘周期數(shù)更改為您喜歡的任何值,可是該值越小,EPT 所導(dǎo)致的系統(tǒng)開銷就越大。對于生產(chǎn)服務(wù)器,您可以將該數(shù)字設(shè)置為某個非常高的數(shù)字(如五百萬),以使系統(tǒng)開銷保持在合理的水平,同時不會完全破壞進(jìn)程中的可用性。正如您預(yù)料的那樣,每五百萬個時鐘周期采樣一次將意味著您需要使應(yīng)用程序運行相當(dāng)長的時間,以便在您的熱點區(qū)域中獲得良好的樣本分布。

            如果您的應(yīng)用程序使用了很多內(nèi)存,則可以選擇讓 EPT 采樣分析器改為在出現(xiàn)頁錯誤時觸發(fā)。這樣,您就可以在數(shù)據(jù)被交換出 RAM 時獲得性能快照,并且可以看到是誰在執(zhí)行推送操作。如果初始分析器運行表明您在代碼外部的區(qū)域中花費了大量時間,則可以告訴分析器改為基于系統(tǒng)調(diào)用來完成采樣。如果您要分析具有大量線程的多線程應(yīng)用程序,則該采樣統(tǒng)計信息會對您在從用戶模式轉(zhuǎn)換到內(nèi)核模式(這表明某些線程可能會不必要地在內(nèi)核對象上阻塞)時的數(shù)據(jù)進(jìn)行拍照。您可以用于采樣觸發(fā)器的最后一些值是 CPU 所支持的各種性能計數(shù)器,例如,分支計數(shù)或緩存丟失。這是一個只有極少數(shù)人才確實需要的高級選項,但是如果您確實需要該數(shù)據(jù),那么知道該數(shù)據(jù)存在也不錯。

            那些忙碌的 Redmontonian 還解決了調(diào)用堆棧問題 — 這是對有用的采樣分析器造成障礙的最大問題之一。正如我在前面提到的那樣,大多數(shù)采樣分析器在采樣時只是對當(dāng)前正在執(zhí)行的指令進(jìn)行拍照。Microsoft 解決了如何將極快的堆棧遍歷結(jié)合到他們的采樣分析器部分中,以便您能夠獲得樣本的好處,并且知道在執(zhí)行該樣本時是如何到達(dá)那里的。這使得將這些快照與代碼重新關(guān)聯(lián)變得更加容易。

            在討論您可以分析的應(yīng)用程序之前,我想提幾件您很可能覺得有趣的事情。第一件事情是,如果您認(rèn)為 Microsoft 是從頭開發(fā)該性能工具的,那么您只猜對了一半。在 Microsoft 內(nèi)部,開發(fā)團(tuán)隊一直在使用 EPT 的前身(名為 Call Attribute Profiler (CAP),它使用儀表化)和 Low Overhead Profiler (LOP) — 一個采樣分析器。由于 Microsoft 開發(fā)了這些工具以收集有關(guān)應(yīng)用程序(例如,操作系統(tǒng)和整個 Office 套件)的性能信息,因此它們甚至不會給您的應(yīng)用程序帶來什么負(fù)擔(dān)。我曾經(jīng)使用過 EPT 的前身,所以我可以告訴您公共版本使用起來會容易多少。此外,它們還具有一些極為有趣的功能(稍后我將予以討論)。

            第二個有趣的事項與 EPT 所支持的技術(shù)有關(guān)。盡管某些人可能認(rèn)為由于 Microsoft 非常偏重于 .NET Framework,因此無法將 EPT 用于 Win32 應(yīng)用程序或本機(jī)代碼,但 EPT 團(tuán)隊實際上已經(jīng)承諾支持所有的 Win32 本機(jī)應(yīng)用程序以及 .NET 代碼。這意味著,無論您使用哪種技術(shù)(ASP.NET、Windows? 窗體、MFC 或 Win32 服務(wù)),您都具有完全的采樣和儀表化支持。您將看到,在 Visual Studio .NET 中,跨技術(shù)使用 EPT 沒有任何差異。

            實際的 EPT 設(shè)置非常平常;只需從 Visual Studio .NET 安裝程序的“Enterprise Tools”樹控件中選擇“Enterprise Performance Tool”即可。當(dāng)然,因為您知道 EPT 仍然是一個測試產(chǎn)品,所以您的第一個反應(yīng)可能是運行虛擬 PC,并在那里安全地包含所有內(nèi)容。但是,為了執(zhí)行采樣分析,EPT 使用內(nèi)核模式設(shè)備驅(qū)動程序來響應(yīng) CPU 性能計數(shù)器中斷,不過令人遺憾的是,虛擬 PC 沒有實現(xiàn)計數(shù)器。它也沒有模擬高級可編程中斷控制器 (APIC),而這兩者都是內(nèi)核設(shè)備驅(qū)動程序完成其工作所必需的。好消息是,如果您沒有額外的計算機(jī)以便安裝 EPT,那么您也并非完全不幸,因為儀表分析器仍然能夠工作。如果您沒有多余的計算機(jī)以便安裝 EPT,那么這是一個讓公司為您購買另一臺計算機(jī)的好借口。


            Animated Algorithm

            要學(xué)習(xí)任何工具的用法,您都需要一個合適的示例應(yīng)用程序,以便能夠最佳地利用該工具。在測試周期的這一時刻,EPT 沒有隨附任何示例,但是在我的硬盤上已經(jīng)有了一個完美的分析器示例。早些時候,我正在嘗試解決如何在 Windows 窗體應(yīng)用程序中使用多線程的問題,因此我編寫了一個名為 Animated Algorithm 的了不起的小程序,該程序可實時激活大量排序算法。圖 1 顯示我的示例應(yīng)用程序已經(jīng)準(zhǔn)備好排序。


            圖 1 正在工作的 Animated Algorithm

            Animated Algorithm 使您可以在窗體的組合框中,從 15 個不同的排序算法中進(jìn)行選擇。“Options”菜單使您可以選擇各個元素交換或設(shè)置之間的休眠時間,以便您可以降低圖形更新的速度。

            我不久前使用 Microsoft? .NET Framework 版本 1.1 編寫了 Animated Algorithm,因此您不會在代碼中找到任何奇特的泛型或新的 BackgroundWorker 項。NSORT 程序集中的排序算法來自由 Jonathan de Halleux、Marc Clifton 和 Robert Rohde 張貼到 The Code Project 上的一篇優(yōu)秀文章(請參閱 Sorting Algorithms In C#),該程序集將算法封裝到公共結(jié)構(gòu)中,以便您可以輕松地替換執(zhí)行元素交換和設(shè)置的類。因為它們具有非常好的體系結(jié)構(gòu),所以我需要關(guān)心的所有內(nèi)容為 UI 部分。

            在本文的其余部分中,我將分析 Animated Algorithm 程序。如果 EPT 團(tuán)隊將該程序作為示例應(yīng)用程序隨附在產(chǎn)品中,則會非常棒。(哈哈。)


            EPT 入門

            在 Visual Studio 2005 Beta 1 中,在哪里可以找到 EPT 當(dāng)然是不明顯的。EPT 在您啟動 Performance Wizard(它位于“Tools”菜單下)時啟動,并且無論是否打開項目,它都存在。請記住,Performance Wizard 所創(chuàng)建的性能會話不是項目的一部分;它們實際上是具有自己的 IDE 窗口(稱為 Performance Explorer)的單獨文件。您可以通過從“File”|“Open”對話框中選擇 PSESS 文件,來打開您創(chuàng)建的性能會話。

            如果您在單步執(zhí)行 Performance Wizard 時沒有打開項目,則所產(chǎn)生的性能會話將與您指定的二進(jìn)制文件相關(guān)聯(lián)。但是,在測試版中,在您指定要運行的二進(jìn)制文件時,必須打開關(guān)聯(lián)的項目。我只是想順便提一下這個小小的技巧,因為當(dāng)我第一次遇到該問題時,它確實讓我困惑不已。

            在您啟動 Performance Wizard 以后,呈現(xiàn)在您面前的第一個屏幕要求您選擇要分析的應(yīng)用程序。如果您打開了一個可生成多個程序集的項目(如 Animated Algorithm),則只能從該向?qū)е羞x取一個程序集。如果要進(jìn)行采樣,則只選取這一個程序集是很好的,因為 EPT 采樣會分析加載的所有程序集(包括那些來自框架類庫的程序集)。但是,如果您要對多個程序集執(zhí)行儀表化分析,則 Performance Wizard 只選擇這一個程序集,因此您將需要在 Performance Explorer 中所生成的性能會話中指定其他項目或程序集。稍后我將向您說明如何完成該工作。

            在選擇了要在性能會話中使用的程序集或項目之后,您必須選取分析方法。在 Performance Explorer 中的任何位置,您都可以在采樣和儀表化之間切換,以滿足自己的需要;您在該向?qū)ы撝羞M(jìn)行的選擇只表示您最初希望執(zhí)行的操作。在選擇了分析方法之后,向?qū)Ь突就瓿闪恕τ?EPT 的最終版本,您將在 Performance Wizard 中具有用于指定附加信息的更多選項。最終版本還將使您可以直接從 Performance Explorer 中創(chuàng)建性能會話。

            圖 2 顯示了 Performance Explorer 在剛剛完成 Performance Wizard 步驟以創(chuàng)建 AnimatedAlgorithms 項目的儀表化運行之后的窗口。要添加另一個項目的輸出二進(jìn)制文件,請右鍵單擊“Targets”文件夾,然后從上下文菜單中選擇“Add Target Project”。如果要添加與該項目沒有關(guān)聯(lián)的特定二進(jìn)制文件,請選擇另一個選項 —“Add Target Binary”。如果您已經(jīng)選擇了“Add Target Project”,則可以在產(chǎn)生的對話框中從已打開的解決方案中選擇其他項目。


            圖 2 Performance Explorer

            如果您已經(jīng)選擇了儀表化運行(它由綠色啟動箭頭下面的下拉列表框中的文本表示),則二進(jìn)制文件儀表化將在程序執(zhí)行之前發(fā)生。如果您不希望針對運行儀表化某個特定的二進(jìn)制文件,則請右鍵單擊該二進(jìn)制文件,并取消選中“Instrument Binary”菜單選項。

            如果您已經(jīng)選擇了采樣分析,并且希望附加到某個正在運行的項目,則單擊“Attach/Detach”按鈕(“Start”按鈕右側(cè)的斜向箭頭)將呈現(xiàn)“Attach Profiler to Process”對話框。通過 EPT,您可以根據(jù)需要附加到任意多的進(jìn)程,以便獲得對應(yīng)用程序的認(rèn)識。“Attach Profiler to Process”對話框還允許您從特定的二進(jìn)制文件中分離分析。在將來的某一期 MSDN Magazine 中,我將更詳細(xì)地討論如何附加到現(xiàn)有的進(jìn)程(特別是為了進(jìn)行 ASP.NET 性能調(diào)整)。

            Performance Explorer 窗口頂部的最后一個按鈕是無所不在的“Properties”按鈕。在啟動分析運行之前,您可能希望瀏覽一下性能會話屬性,以設(shè)置幾個關(guān)鍵屬性。第一個屬性位于“General”選項卡上,它是您希望為性能會話存儲性能報告的位置。在分析項目時,默認(rèn)設(shè)置是將報告存儲在與解決方案相同的目錄中。但更好的做法是將性能會話和它們的相應(yīng)報告放置在它們自己的目錄中,以便您可以更容易地存儲特定的運行集。這樣還可以更容易地分析之前和之后的情況,以便查看您所進(jìn)行的代碼更改的影響。

            在“General”選項卡上,您還可以在儀表化和采樣分析之間切換(這會更改在 Performance Explorer 中顯示的值)。在我進(jìn)行的性能調(diào)整中,我喜歡將特定的會話專用于單個類型的分析,以避免出現(xiàn)與報告有關(guān)的混淆。沒有任何事情阻止您為所有種類的特定方案(涵蓋從分析類型到單個二進(jìn)制文件儀表化的所有方案)創(chuàng)建數(shù)以百計的不同性能會話文件。我還將提一下“General”選項卡上的最后一個項,它具有一個非常誘人的名稱 —“Managed Allocation Profiling”,相信這會使您感到更加好奇。在我討論完常規(guī)分析之后,我將返回到該項。

            “Performance Session”屬性頁上的另一個有趣的選項卡是“Sampling”選項卡(請參見圖 3)。在這里,您可以告訴 EPT 您要執(zhí)行哪種類型的采樣。正如我在前面提到的那樣,您對于希望如何進(jìn)行采樣具有非常好的控制。


            圖 3 各種 EPT 采樣計數(shù)器選項

            在執(zhí)行分析運行時,EPT 會在二進(jìn)制文件在硬盤中所處的位置上將其儀表化。如果您希望將儀表化的二進(jìn)制文件移動到另一個位置,請選擇“Performance Session”屬性頁中的“Binary”選項卡,然后選中“Relocate Instrumented Binaries”(它與 REBASE 樣式的重定位絕對沒有任何關(guān)系),并且指定您希望將更改后的二進(jìn)制文件移至何處。

            “Instrumentation”選項卡使您可以指定希望在儀表化發(fā)生之前和之后運行的程序。如果您需要對儀表化的二進(jìn)制文件執(zhí)行其他任務(wù)(例如,將其移動到全局程序集緩存中或 Web 服務(wù)器上的特定位置),則該選項卡可能很有用。“Advanced”選項卡在該測試版中未公開。最后,通過“Counters”選項卡,您可以告訴 EPT 從系統(tǒng)的 CPU 中收集其他數(shù)據(jù),例如,L2 或 L3 緩存讀取不中。顯然,這些選項是只有少數(shù)開發(fā)人員才會需要的非常高級的選項,但是如果您確實需要它們,那么它們可以發(fā)揮巨大的作用。

            在我繼續(xù)討論查看采樣數(shù)據(jù)之前,我想提一下,“Performance Explorer”窗口可以根據(jù)您的需要打開任意多個性能會話。當(dāng)您希望觀察特定的前后方案,或者希望用不同的儀表化二進(jìn)制文件執(zhí)行單獨的測試運行時,這一點極為有用。當(dāng)您打開多個性能會話時,應(yīng)當(dāng)確保右鍵單擊特定的會話,選擇“Set as Current Session”以便讓該會話的設(shè)置執(zhí)行,然后將報告歸檔到它的報告節(jié)點中。


            查看分析器數(shù)據(jù)

            將性能會話設(shè)置為您希望執(zhí)行的操作以后,就可以啟動分析了。我將首先對 Animated Algorithm 執(zhí)行采樣分析,以查看我是否可以找到一些熱點。從采樣中獲得良好數(shù)據(jù)的關(guān)鍵在于執(zhí)行較長時間的運行。對于 Animated Algorithm,我會將 15 個排序算法中的每一個算法運行兩次,并將采樣設(shè)置為默認(rèn)的一百萬個時鐘周期。

            在完成某個運行之后,EPT 會將該運行的報告放到性能會話的“Reports”文件夾中。EPT 在運行期間收集原始性能數(shù)據(jù),并將其流式傳輸?shù)綀蟾嫖募校ú蛔鋈魏畏治觯_@樣,您可以在運行應(yīng)用程序時避免所有系統(tǒng)開銷,但是您將為大型報告文件付出代價。我剛才完成的運行的采樣報告文件大小為 3.70MB,它用了大約三分鐘才完成。請確保您在運行 EPT 時具有大量的磁盤空間。

            所有數(shù)據(jù)分析(它必然伴有調(diào)用堆棧的生成以及性能數(shù)字的計算)都在您打開報告文件時發(fā)生。對于測試版,在打開文件時速度可能會降低。看起來視圖好像處于無限循環(huán)中,但是,如果進(jìn)度欄正在報告窗口中移動,那么請您耐心一些,文件最終將彈出。

            任何分析運行中的第一個視圖是“Performance Report Summary”,它顯示在剛剛完成的 Animated Algorithm 采樣運行的圖 4 中。不出所料,采樣將發(fā)生在整個應(yīng)用程序中,因此您正在查看的信息也就是您將在應(yīng)用程序中看到的內(nèi)容:大部分工作都發(fā)生在框架類庫或操作系統(tǒng)內(nèi)部。如果您確實在采樣“Summary”視圖中看到了您的一個方法,則您很可能看到了一個性能問題。


            圖 4 EPT 采樣性能報告摘要

            快速瀏覽一下圖 4,您可能想知道 Inclusive Sampled 和 Exclusive Sampled 之間的區(qū)別。Exclusive Sampled 意味著該方法在取樣時位于堆棧的頂部。換句話說,它是當(dāng)前正在執(zhí)行的函數(shù)。Inclusive Sampled 意味著該函數(shù)在取樣時出現(xiàn)在調(diào)用堆棧中。因而,包含方法是當(dāng)前正在執(zhí)行的方法的調(diào)用方。

            在采樣方案中,一個方法在調(diào)用堆棧 (Inclusive Sampled) 中出現(xiàn)的次數(shù)越多,該函數(shù)在執(zhí)行中花費的時間就越多,因此這里是您需要重點關(guān)注以進(jìn)行性能調(diào)整的地方。對于 Exclusive Sampled 函數(shù)而言,函數(shù)在那里頻繁出現(xiàn)表明該函數(shù)正在被頻繁地調(diào)用,但是它的執(zhí)行實際上可能非常快速。對于像 Animated Algorithm 這樣需要進(jìn)行大量圖形處理的應(yīng)用程序,我完全能夠預(yù)料到 GDIPLUS.DLL 中的某個函數(shù)將靠近剛剛顯示的列表的頂部。在圖 4 中,位于 GDIPLUS.DLL 中偏移量 0x5B8D 處的函數(shù)(它恰好是 FLOOR 函數(shù))被一直調(diào)用,以便計算在屏幕上的哪個位置顯示某些內(nèi)容。當(dāng)您觀察性能運行時,請確保設(shè)置符號服務(wù)器以獲得可能存在的最佳信息。在撰寫本文時,我使用了 EPT 的未發(fā)布版本,因而符號尚不可用。

            在我跳到其他視圖中以前,我希望儀表化 Animated Algorithm,并且完成與我針對采樣分析器完成的運行相同的運行,以便顯示儀表化運行的性能報告摘要。正如您可以猜到的那樣,儀表化的運行會生成比采樣運行多得多的數(shù)據(jù)。對于該運行,我儀表化了 Animated Algorithm 中的全部五個程序集,并最終得到一個 375MB 大小的會話文件。

            采樣和儀表化數(shù)據(jù)之間的主要區(qū)別是:采樣查看整個進(jìn)程空間,并且將顯示框架類庫或操作系統(tǒng)內(nèi)部(換句話說,就是您在其中不具有源代碼的位置)的調(diào)用。另一方面,儀表化只查看應(yīng)用程序以及您在非儀表化模塊上直接調(diào)用的方法。例如,如果您具有一個“Hello World!”應(yīng)用程序,并且它的 Main 只調(diào)用 Console.WriteLine,則您將獲得 Main 中任何工作的計時信息以及 Console.WriteLine 長度的計時信息,但是您不會獲得有關(guān) Console.WriteLine 方法的任何詳細(xì)信息。

            圖 5 顯示了儀表化運行的性能報告摘要。第一個表“Most Called Functions”顯示了頻繁使用的函數(shù)。該表中的第一列被錯誤標(biāo)記為時間;它實際上表示對該函數(shù)的調(diào)用次數(shù)。百分比列顯示了對該特定函數(shù)進(jìn)行的調(diào)用總次數(shù)所占的百分比。在大多數(shù)運行中,您將在這里看到框架類庫或操作系統(tǒng)函數(shù)。如果您看到一些來自您自己的代碼的函數(shù),則您最好了解一下您為什么如此頻繁地調(diào)用該特定函數(shù)。


            圖 5 儀表化運行的摘要

            “Functions with Most Individual Work”表列出了那些花費大部分時間以僅僅執(zhí)行該函數(shù)(沒有任何其他函數(shù)調(diào)用)的方法。這也稱為該函數(shù)的獨占時間。對于測試版本,“Time”列的單位為時鐘走格數(shù)。對于最終版本,單位將是毫秒。但是,我認(rèn)為性能運行的實際原始單位對于分析沒有用。最重要的數(shù)字是百分比。在觀察性能問題時,您希望知道,與應(yīng)用程序中的所有其他方法相比,哪個方法占用了最長的時間。您在觀察像 3519639455 和 3492589504 這樣的兩個數(shù)字時,很難對它們進(jìn)行什么比較。幸運的是,該表包含百分比,而我對 EPT 團(tuán)隊的建議是從圖表中丟棄原始數(shù)據(jù)。

            最后一個表“Functions Taking Longest”顯示方法的實際時間(也稱為跑表時間或運行時間)。分析器記錄方法的入口點時間和出口點時間,并將這兩個值相減。該數(shù)字涵蓋了被調(diào)用的所有子方法、所有上下文切換以及該方法執(zhí)行的休眠。在圖 5 中,您可以看到 System.Windows.Forms.Application.Run 占用了最長時間,就像您對 Windows 窗體應(yīng)用程序所預(yù)料的那樣。盡管很多開發(fā)人員將注意力集中于獨占時間,但這只是整個性能狀況的一小部分。如果方法正在對數(shù)據(jù)庫進(jìn)行調(diào)用或者進(jìn)行 Web 服務(wù)調(diào)用,則您的方法在運行時所在的線程將在等待這些調(diào)用返回數(shù)據(jù)時阻塞,從而使得該線程從 CPU 中被移走。通過密切關(guān)注方法的運行時間,您可以找到代碼中正在降低應(yīng)用程序運行速度的部分。

            盡管摘要視圖很不錯,但您最感興趣的將是查看代碼在何處阻塞了系統(tǒng)的其余部分(對于采樣運行而言),或者阻塞了應(yīng)用程序的其他方法(對于儀表化運行而言)。這是“Function”視圖的職責(zé)范圍 — 通過單擊報告窗口底部的“Function”按鈕可以選擇該視圖。您還可以雙擊“Summary”視圖的任何方法以跳至“Function”視圖。

            對于采樣運行,“Function”視圖顯示了至少一個包含捕獲中所有函數(shù)捕獲的列表。對于儀表化運行,您將看到作為該運行的一部分調(diào)用的所有儀表化方法。無論您正在執(zhí)行哪種類型的分析,都會在“Function”視圖中顯示很多數(shù)據(jù),因此您可以對代碼的狀況有一點兒感覺。

            默認(rèn)情況下,采樣“Function”視圖顯示“Inclusive Samples”列和“Exclusive Samples”列。由于我喜歡百分比數(shù)字,因此我右鍵單擊了列標(biāo)題以向列標(biāo)題中添加“Inclusive Percent”和“Exclusive Percent”。如果您要對多進(jìn)程系統(tǒng)進(jìn)行采樣,則可能希望包含其他列(例如,“Process Name”或“Process ID”),以便您可以標(biāo)識哪個方法采樣與哪個進(jìn)程相配。您還可以在儀表化“Function”視圖中設(shè)置列標(biāo)題,但是您將具有不同的標(biāo)題組以供選擇。

            在“Function”視圖中分析采樣運行時,我喜歡首先掃一眼“Function”視圖的頭幾個按“Inclusive Samples”列排序的頁,以了解正在執(zhí)行的方法。如果我在頭幾個頁中沒有看到我的任何方法,則我會右鍵單擊“Function”視圖并選擇“Group by Module”,以便獲得樹報告視圖。當(dāng)您將函數(shù)按模塊分組時,按特定列排序可以正確執(zhí)行 — 這是一項很不錯的功能。

            對于儀表化運行,“Function”視圖具有更多要顯示的列。如果您擁有一臺 40 英寸的顯示器,則無需最大化 Visual Studio .NET 窗口就應(yīng)當(dāng)能夠看到所有這些列。對于我們中的其他人而言,查看“Function”視圖的最佳方式是按 Alt + Shift + Enter 以切換到全屏幕模式。

            在這些列中,“Function”視圖中的儀表化運行使用我在前面解釋過的“包含”和“獨占”術(shù)語。但是,還有另一個使人混淆的術(shù)語:應(yīng)用程序。正如我提到的那樣,運行時間是從一個儀表化點到另一個儀表化點的總時間,而不管該線程可能進(jìn)行了哪些上下文切換。應(yīng)用程序時間的思想是 EPT 將提取出在這些上下文切換中所花費的時間,以便您可以看到您的代碼在 CPU 中實際執(zhí)行的時間圖 6 列出了您將在儀表化“Function”視圖中看到的不那么明顯的列的定義。您可能希望將它傳送到顯示器上,直到 EPT 的聯(lián)機(jī)幫助問世。

            在觀察儀表化運行的“Function”視圖時,我添加了這些列以查看各種計時的百分比值,移除原始數(shù)字時間列,并且添加了兩個轉(zhuǎn)換列。這為我提供了有關(guān)該運行的更清晰視圖。我在排序時所依據(jù)的第一個列是“% Application Exclusive Time”,因為我希望看到哪個函數(shù)正在完成大部分工作。由于儀表化在方法進(jìn)行的所有子調(diào)用周圍放入了探測,所以您完全有可能在該列表的頂部看到框架類庫或操作系統(tǒng)。實際上,對于我的 Animated Algorithm 運行,System.Drawing.SolidBrush.ctor 和 System.Drawing.Brush.Dispose 在 Application Exclusive Time 百分比中被列為第一和第二,其百分比分別為 14.982% 和 14.867%。我編寫的第一個函數(shù)是位于第三位的 Bugslayer.SortDisplayGraph.SorterGraph.UpdateSingleFixedElement(其百分比為 12.217%),它在圖形中繪制單獨的條。根據(jù)應(yīng)用程序類型的不同,我在查看“Function”視圖時可能會選擇按其他列排序。如果存在 Web 服務(wù)或數(shù)據(jù)庫調(diào)用,則我將查看 % Elapsed Inclusive Time,以便可以看到是否有特定方法卷入到長時間阻塞中。對于像 Animated Algorithm 這樣的應(yīng)用程序,我還將查看 Application Inclusive Time 的百分比。

            基于我的儀表化運行中的上述數(shù)字,我很想查明是誰在對 SolidBrush 方法進(jìn)行這些調(diào)用,因此我右鍵單擊 .ctor 方法并選擇“Show in Caller/Callee”視圖,以便查看是誰在調(diào)用該方法。該視圖(它對于采樣分析也可用)使您一眼就可以看出目標(biāo)方法的所有調(diào)用方,以及該目標(biāo)方法調(diào)用的所有方法。

            因為 .ctor 方法沒有儀表化,所以“Caller/Callee”視圖將不會顯示任何被調(diào)用方,但是它顯然會顯示調(diào)用方。我雙擊了這個唯一的調(diào)用方,它恰好是具有第三高 Application Exclusive Time 并具有圖 7 所示視圖的 UpdateSingleFixedElement 方法。

            圖 7 中,位于視圖中部的下拉組合框是目標(biāo)方法(在本例中為 UpdateSingleFixedElement)。方法上方的網(wǎng)格包含了目標(biāo)方法的所有調(diào)用方(調(diào)用方)。目標(biāo)方法下方的網(wǎng)格包含了目標(biāo)方法調(diào)用以完成其工作的所有方法(被調(diào)用方)。如果您希望查看是誰調(diào)用了特定調(diào)用方,請雙擊該調(diào)用方方法,該方法將變?yōu)槟繕?biāo)方法,并且您將看到原始目標(biāo)方法下降到被調(diào)用方部分中。實質(zhì)上,您只是將堆棧遍歷了一遍。

            僅僅基于圖 7 中的視圖,您就可以辨別出潛在的性能問題。Animated Algorithm 似乎不具有任何突出的性能問題,但是 SolidBrush .ctor 和 Dispose 占用了如此多的時間并且都在 UpdateSingleFixedElement 方法內(nèi)部調(diào)用(調(diào)用了 351,872 次),這個事實表明我做了一件愚蠢的事情 — 我每次都通過該函數(shù)創(chuàng)建畫筆,而實際上應(yīng)該將其緩存。當(dāng)我在將來的某一期 MSDN Magazine 中開始用 EPT 分析代碼時,您還將看到 Animated Algorithm 的其他一些問題。

            數(shù)據(jù)的最后一個常用視圖是“Callstack”視圖。在這里,您可以通過更具層次性的方式看到您在“Caller/Callee”窗口中觀察到的調(diào)用堆棧。對于采樣運行,您將在“Callstack”視圖的頂層看到很多的條目,因為這些條目中的每一個都代表一個包含獨占樣本的唯一點。當(dāng)您在采樣運行中展開項時,您還將看到,在相同級別偶爾會存在一些項,這些項指示位于根部的函數(shù)具有多個引向它的調(diào)用樹。根位置中顯示的項是棧頂。

            對于儀表化運行,“Callstack”窗口將具有與應(yīng)用程序中的每個線程相對應(yīng)的根元素。因為 Animated Algorithm 只有兩個線程,所以您只能在樹根級別看到兩個項。在“Callstack”視圖中,您可以看到絕對調(diào)用堆棧(從儀表化的第一個方法向下到最后一個方法),因此您可以真正了解應(yīng)用程序的執(zhí)行方式。我已經(jīng)有很多次對我認(rèn)為代碼所完成的工作和代碼實際上完成的工作之間的差異感到吃驚。

            您可以花費大量時間在“Callstack”窗口中分析代碼。當(dāng)通過應(yīng)用程序觀察特定的蹤跡時,您可以通過選擇感興趣的特定節(jié)點,向下移動,右鍵單擊,并選擇“Set Root”菜單選項,來消除大量噪音。在圖 8 中,我希望查看 NSort.SwapSorter.Sort 進(jìn)行的所有調(diào)用,因此將它設(shè)置為根可以消除 UI 線程的影響。

            在將來的某一期中,我將更詳細(xì)地討論 EPT 顯示區(qū)域中的最后兩個選項卡:“Trace”和“Type”。在“Type”視圖中,您可以觀察已經(jīng)在應(yīng)用程序中分配的對象。它在測試版中有效。當(dāng)我在前面討論性能會話屬性時,我提到過在“General”選項卡上有一個“Managed Allocation Profiling”部分。如果您選擇“Allocations-only”單選按鈕,則 EPT 會填充“Type”視圖。在測試版中,報告看起來類似于其他許多工具中的報告,但是數(shù)據(jù)收集似乎不像在其他工具中那樣具有如此之多的系統(tǒng)開銷。最后,要了解 Enterprise Performance Tool 團(tuán)隊的想法以及有關(guān)該工具的更多信息,請確保在 blogs.msdn.com/profiler 查看他們的網(wǎng)絡(luò)日記。

            John Robbins 是 Wintellect 的創(chuàng)始人之一,該公司是一家專門致力于 Windows 和 .NET Framework 的軟件咨詢、教育和開發(fā)公司。他的最新著作是“Debugging Applications for Microsoft .NET and Microsoft Windows”(Microsoft Press, 2003)。要聯(lián)系 John,請訪問 www.wintellect.com

            posted on 2006-04-27 17:46 夢在天涯 閱讀(1005) 評論(0)  編輯 收藏 引用 所屬分類: C#/.NETData ArithmeticVS2005/2008

            公告

            EMail:itech001#126.com

            導(dǎo)航

            統(tǒng)計

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1811124
            • 排名 - 5

            最新評論

            閱讀排行榜

            色狠狠久久AV五月综合| 中文成人久久久久影院免费观看| 区亚洲欧美一级久久精品亚洲精品成人网久久久久| 亚洲精品无码久久一线| 中文字幕精品久久| 国产香蕉久久精品综合网| 久久精品综合网| 一本久久a久久精品亚洲| 久久午夜夜伦鲁鲁片免费无码影视| 日韩久久无码免费毛片软件| 欧美久久亚洲精品| 久久人人添人人爽添人人片牛牛| 97香蕉久久夜色精品国产| 一本久久a久久精品vr综合| 久久久一本精品99久久精品88| 国产精品久久久久9999| 精品久久久久中文字幕一区| 亚洲一级Av无码毛片久久精品| 国产成人综合久久精品红| 亚洲精品无码久久久久| 久久精品国产亚洲AV电影| 88久久精品无码一区二区毛片| 99久久免费只有精品国产| 日日狠狠久久偷偷色综合免费| 精品人妻伦九区久久AAA片69 | 亚洲国产精品久久久天堂| 99久久精品国内| 欧美久久综合九色综合| 久久久久久午夜成人影院 | 久久中文字幕精品| 日韩人妻无码精品久久久不卡 | 无码人妻久久一区二区三区蜜桃| 亚洲中文字幕无码久久2020| 久久99免费视频| 久久无码AV中文出轨人妻| 久久香蕉国产线看观看99| 伊色综合久久之综合久久| 国产精品久久久久天天影视| 国产精品99久久久久久宅男小说| 91精品国产91久久久久久青草| 综合久久一区二区三区|