免费在 Visual Studio 中对 C++ 应用程序进行性能分析






4.97/5 (48投票s)
一种使用免费工具(vsperfcmd、vsperfreport 和一个用于查看结果的 C# 应用程序)对 C++ 应用程序进行性能分析的方法
引言
虽然 Visual Studio 的 Team 版或 Premium 版包含性能分析器,但例如 Professional 版的用户却缺少此功能。在本文中,我将介绍一种使用免费工具和简单的应用程序对 C++ 应用程序进行性能分析的方法,该应用程序可将结果以信息丰富的方式呈现。

当然,最终的解决方案不像集成性能分析器那样方便,但如果您仅在发现瓶颈时才使用性能分析,那么此方法肯定足够了 - 而且便宜 5,000 欧元。
以下方法已在 Visual Studio 2008 Professional 和 Visual C++ 2010 Express 中进行了测试。
方法
该方法包括四个步骤
- 使用 Visual Studio(所有版本均可)生成特殊的“/PROFILE”生成。
- 使用免费的 Microsoft 工具“VSPerfCmd”对新编译的应用程序进行性能分析。
- 使用“
VSPerfReport
”将生成的 .vsp 文件转换为 .csv 文件。 - 使用附带的 Profile Result Viewer 分析生成的(非常大的)csv 文件。
生成 /PROFILE 生成
注意:以下步骤应在发布生成且启用调试符号的情况下进行。
在 Visual Studio 2008 中,转到解决方案资源管理器,选择项目并打开属性页。在“配置属性”部分,选择“链接器”-“高级”。
将“性能分析”设置为“启用性能分析信息 (/PROFILE)”(其他 Visual Studio 版本上的确切步骤可能有所不同)。
编译项目。
生成性能分析报告 (vsp)
首先,安装 Visual Studio 性能工具。您可以在此链接找到 Visual Studio 2008 Service Pack 1 Stand-Alone Profiler 。生成报告需要在命令行中输入一些命令。
命令行准备工作
打开命令提示符。定义一个指向性能工具的快捷方式,并切换到您的应用程序所在的文件夹。
set pt="C:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools"
cd [my_app_folder]
分析整个应用程序运行
最简单的方法是分析应用程序的整个运行时间。
:: Start the profiler
%pt%\vsperfcmd /start:sample /output:my_sampled_data.vsp
:: Launch the application via the profiler
%pt%\vsperfcmd /launch:my_app.exe
:: Shut down the profiler (this command waits, until the application is terminated)
%pt%\vsperfcmd /shutdown
仅分析应用程序运行时间的一部分
也可以只分析应用程序运行时间的一部分。
这里的处理会有点繁琐,所以我认为最好实现一个简单的应用程序来自动化以下步骤。无论如何,我从未真正有过仅分析运行时间一部分的需求,因为我总是(也许通过修改应用程序的启动代码)能够编写出将 90% 的时间花费在相关部分的代码。但是,如果您无法充分修改代码,请执行以下附加步骤。
如上所述启动 vsperfcmd,然后将其附加到您的应用程序。
:: Start the profiler
%pt%\vsperfcmd /start:sample /output:my_sampled_data.vsp
:: Send the profiler to a waiting state
%pt%\vsperfcmd /globaloff
:: Attach to your application by specifying the pid
%pt%\vsperfcmd /attach:[pid]
附加到您的应用程序后,执行所有必要的准备工作。现在,启动您想要分析的函数并激活性能分析器。
:: Activate the profiler
%pt%\vsperfcmd /globalon
当函数完成时(或者您认为时间已足够),停止性能分析。
:: Detach the profiler from your application
%pt%\vsperfcmd /detach
:: Shut down the profiler
%pt%\vsperfcmd /shutdown
将性能分析报告转换为 csv 文件
工具 vsperfreport 加载符号文件(.pdb)并将其与生成的报告(.vsp)合并以创建 .csv 文件。
:: generate the report files (.csv)
%pt%\vsperfreport /summary:all my_sampled_data.vsp
如果您也有兴趣了解系统文件中的调用,也可以指定符号服务器或本地缓存的路径。
%pt%\vsperfreport /summary:all my_sampled_data.vsp
/symbolpath:"srv*C:\MySymbolCache*http://msdl.microsoft.com/download/symbols"
查看报告
原则上,上面的 csv 文件可以用任何电子表格应用程序打开,但它们通常很大,并且不易直接理解。
因此,我编写了一个小型应用程序,它可以解析其中一个生成的文件(名为“...CallerCalleeSummary.csv”的文件),并以树状视图呈现,按总百分比排序。从这个视图开始,应该很容易找到性能问题的原因。就我而言,我在 C++ 遗留代码中发现了几个瓶颈,这些瓶颈是我仅通过查看代码而永远找不到的。
Using the Code
附件中还有一个我生成了性能分析的 C++ 小应用程序。生成的 .vsp 和 .csv 文件包含在“Release”子文件夹中。使用 ProfileResultViewer
打开“my_sampled_data_CallerCalleeSummary.csv”应类似于我上面提供的屏幕截图。
关注点
- 性能分析报告仅显示函数的统计信息,不显示单独的行。
- 内联的函数将不包含在性能分析中,因为它们也永远不会出现在本机调用堆栈中。
- 提供的
treeview
并非严格的层次结构:如果 A 调用 B,那么在提供的视图中,B 可能看起来比 A 占用更多时间。这是因为显示的是总百分比,也就是说,它没有显示 B 在被 A 调用时花费了多少时间,而是显示 B 总共花费了多少时间。我不确定 csv 文件是否包含足够的信息来恢复更详细的数字。
当然,上述步骤中的一些可以轻松集成到 GUI 应用程序中,但目前我描述的这种方法对我来说已经足够简单了。
历史
- 2011.11.01:初始版本
- 2012.07.11:ProfileResultViewer 处理大型 CSV 文件速度提升(感谢 SteelixB 提供的提示)