使用 xperf 进行性能分析

Xperf 是 Microsoft Windows Performance Toolkit 的一部分,其功能类似于 Shark、oprofile 和(某些方面)dtrace/Instruments。对于堆栈回溯,需要 Windows Vista 或更高版本;我在 XP 上完全没有测试过。

此页面适用于 xperf 4.8.7701 或更高版本。要查看您的 xperf 版本,可以在命令行上运行 “xperf”(不带任何参数),或启动 “xperfview” 并查看“帮助” -> “关于性能分析器”。(请注意,这并非“关于”窗口中的第一个版本号;那是 Windows 版本。)

如果您使用的是较旧的版本,则会遇到错误,尤其是在本地构建的符号加载方面。

安装

对于所有版本,这些工具都包含在最新的 Windows 7 SDK (SDK 版本 7.1){.external} 中。使用 Web 安装程序至少安装“Win32 开发工具”。SDK 安装完成后,在 SDK 安装位置的 Redist/Windows Performance Toolkit 文件夹中(通常是 Program Files/Microsoft SDKs/Windows/v7.1/Redist/Windows Performance Toolkit)执行 wpt_x86.msiwpt_x64.msi 以实际安装 Windows Performance Toolkit 工具。

Windows SDK 可能已经安装了它。检查 C:\Program Files\Microsoft Windows Performance Toolkit 是否已存在。

对于 64 位 Windows 7 或 Vista,您需要进行注册表调整,然后重新启动以启用堆栈回溯

REG ADD "HKLM\System\CurrentControlSet\Control\Session Manager\Memory Management" -v DisablePagingExecutive -d 0x1 -t REG_DWORD -f

符号服务器设置

使用最新版本的 Windows Performance Toolkit,您可以通过程序中的“跟踪”菜单直接修改符号路径。只需确保在启用“加载符号”和打开摘要视图之前设置符号路径即可。您还可以修改 _NT_SYMBOL_PATH_NT_SYMCACHE_PATH 环境变量以使这些更改永久生效。

包含 Mozilla 和 Microsoft 符号服务器配置的标准符号路径如下所示

_NT_SYMCACHE_PATH: C:\symbols  _NT_SYMBOL_PATH: srv*c:\symbols*http://msdl.microsoft.com/download/symbols;srv*c:\symbols*http://symbols.mozilla.org/firefox/

要添加您自己构建的符号,请将 C:\path\to\objdir\dist\bin 添加到 _NT_SYMBOL_PATH 中。与所有 Windows 路径一样,符号路径使用分号 (;) 作为分隔符。

确保在 Windows Performance Analyzer (xperfview) 中选择了“跟踪” -> “加载符号”菜单选项。

xperf 和符号似乎存在一个错误;它对何时编辑符号路径非常敏感。如果在程序中更改它,则必须关闭所有摘要表并重新打开它们才能使其获取新的符号路径数据。

您需要同意 Microsoft 符号的使用条款 - 如果没有提示您,则符号路径的配置不正确。(再次确保目录存在;如果不存在,则会发生静默错误。)

快速入门

默认情况下,所有这些工具都位于 C:\Program Files\Microsoft Windows Performance Toolkit 中。要么从那里运行这些命令,要么将该目录添加到您的路径中。您需要使用提升的命令提示符来启动或停止性能分析。

开始记录数据

xperf -on latency -stackwalk profile

“Latency”是一个特殊的提供程序名称,它会打开一些预定义的内核提供程序;运行“xperf -providers k”以查看提供程序和组的完整列表。您可以组合提供程序,例如“xperf -on DiagEasy+FILE_IO”。“-stackwalk profile”告诉 xperf 为每个 PROFILE 事件捕获一个堆栈;您也可以执行“-stackwalk profile+file_io”以在每个 CPU 性能分析滴答和每个文件 IO 完成事件上捕获堆栈。

停止

xperf -d out.etl

查看

xperfview out.etl

MSDN 的“快速入门{.external}”页面更详细地介绍了这一点,并且还很好地解释了如何使用 xperfview。我不会在这里重复它,因为我会使用基本上相同的屏幕截图,所以请查看那里。

“堆栈”视图将提供类似于 shark 的结果。

堆性能分析

xperf 具有用于堆分配性能分析的良好工具,但它们有一个主要限制:您无法使用 jemalloc 构建并生成堆事件。默认的 Windows CRT 分配器在碎片方面非常糟糕,即使只有一小部分内存正在使用,也会导致内存使用量急剧上升。但是,即使是这样,它也是跟踪分配/释放的有效方法。

捕获堆数据

“-heap”选项用于设置堆跟踪。Firefox 会生成大量事件,因此您可能还需要调整 BufferSize/MinBuffers/MaxBuffers 选项以确保不会丢失事件。此外,在记录堆栈时,我发现堆跟踪通常缺少模块信息(我相信这是 xperf 中的一个错误)。可以通过同时捕获非堆数据来解决此问题。

要启动跟踪会话,启动一个新的 Firefox 实例

xperf -on base  xperf -start heapsession -heap -PidNewProcess "./firefox.exe -P test" -stackwalk HeapAlloc+HeapRealloc -BufferSize 512 -MinBuffers 128 -MaxBuffers 512

要停止会话并合并生成的文件

xperf -stop heapsession -d heap.etl  xperf -d main.etl  xperf -merge main.etl heap.etl result.etl

“result.etl”将包含合并后的数据;您可以删除 main.etl 和 heap.etl。请注意,可以为非堆性能分析捕获更多数据;例如,您可能希望能够将堆事件与性能数据相关联,因此您可以执行“xperf -on base -stackwalk profile”。

在查看器中,当查看堆事件的摘要数据时(“Heap Allocations Outstanding”等都导致相同的摘要图表),会列出 3 种类型的分配 - AIFI、AIFO、AOFI。这是“Allocated Inside, Freed Inside”、“Allocated Inside, Freed Outside”、“Allocated Outside, Freed Inside”的缩写。这些指的是为摘要图选择的时段;例如,属于 AOFI 类别的某个东西是在选定时段开始之前分配的,但释放事件发生在内部。

提示

  • 在摘要视图中,可以左右拖动黄色条来更改分组 - 例如,将其拖到“模块”列的左侧,以便仅按进程(左侧的内容)进行分组,以便无论它们位于哪个模块,都可以按权重顺序获取符号。

  • 拖动列周围会以各种方式更改分组;进行实验以获取您正在寻找的数据。还可以尝试启用和禁用列;删除列将允许聚合数据,而无需考虑该列的贡献。

  • 禁用除一个核心之外的所有核心将使数字加起来为 100%。这可以通过运行“msconfig”并在“启动”选项卡中转到“高级选项”来完成。

构建 Firefox

要从 Firefox 构建中获取良好的数据,务必在 mozconfig 中使用以下选项进行构建

export CFLAGS="-Oy-"  export CXXFLAGS="-Oy-"

这会禁用帧指针优化,从而使 xperf 能够更好地展开堆栈。无需此选项也可以很好地捕获跟踪(例如,从 nightly 版本),但堆栈信息将无用。

ac_add_options --enable-debug-symbols

这为我们提供了符号。

更多信息

Microsoft 的 xperf 文档 非常好;此工具有很多深度,您应该在那里查找更多详细信息。