65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.97/5 (48投票s)

2011年1月11日

CPOL

4分钟阅读

viewsIcon

291058

downloadIcon

6548

一种使用免费工具(vsperfcmd、vsperfreport 和一个用于查看结果的 C# 应用程序)对 C++ 应用程序进行性能分析的方法

引言

虽然 Visual Studio 的 Team 版或 Premium 版包含性能分析器,但例如 Professional 版的用户却缺少此功能。在本文中,我将介绍一种使用免费工具和简单的应用程序对 C++ 应用程序进行性能分析的方法,该应用程序可将结果以信息丰富的方式呈现。

profileWithVsPerfCmd/Screenshot2.png

当然,最终的解决方案不像集成性能分析器那样方便,但如果您仅在发现瓶颈时才使用性能分析,那么此方法肯定足够了 - 而且便宜 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 版本上的确切步骤可能有所不同)。

profileWithVsPerfCmd/screenshot1.png

编译项目。

生成性能分析报告 (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 提供的提示)
© . All rights reserved.