在上一章中,咱们研究了为何性能很重要,甚至诊断了一个简单的性能问题。在本章中,咱们将总览执行性能分析的其余方法。为了证实这些问题,咱们将诊断与练习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的性能测量。