首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

使用C+Build Insights找到编译过程中的瓶颈

找到编译时间的瓶颈

C++ Build Insights提供了多种分析C++编译时间的方法。在本文中,我们将会讨论可用来识别编译过程中的瓶颈的两种方法:

1) 使用vcperf工具进行手动分析。

2) 使用C++ Build Insights SDK以程序化的方式进行分析。

我们提供了一个案例研究,展示了如何使用这些工具来加快Git for Windows这一开源项目的编译速度。我们希望这些教程在分析你自己的工程编译时能派上用场。

使用vcperf

vcperf工具可以用来捕获工程编译过程的信息并在Windows Performance Analyzer(WPA)工具中进行查看。

具体步骤如下:

1. 下载最新版本的Visual Studio 2019。

2. 从最新版本的Windows ADK中获取WPA工具。

3. 按照vcperf的文档说明,将WPA配置为与C++ Build Insights一起使用。在这个阶段,你可以可以考虑自行编译一份vcpef作为一个可选的步骤。

4. 打开具有管理员权限的[x64 Native Tools Command Prompt for VS 2019]。

5. 获取工程编译信息:

5.1 执行指令:[vcperf /start MySessionName]

5.2 在系统的任何位置编译你的工程,甚至是不需要在Visual Studio中编译(因为vcperf会在整个系统级别上收集工程编译信息)。

5.3 执行指令:[vcperf /stop MySessionName outputFile.etl]。这将会将工程编译信息拷贝到outputFile.etl文件中。

6. 在WPA工具中打开收集到的编译信息。

在WPA中使用Build Explorer视图

首次在WPA中打开编译信息时,你需要做的第一件事就是打开[BuildExplorer]视图。可以通过将其从[GraphExplorer]窗口拖到[Analysis]窗口中来进行操作,如下图所示:

Build Explorer视图提供了4个预设选项,您可以在浏览工程编译信息时选择需要的视图:

1. Timelines

2. Invocations

3. Invocation Properties

4. Activity Statistics

可以通过点击视图顶部的下拉菜单来选择你需要的视图,如下图所示:

接下来,我们将对这4个预设视图分别进行讲解。

预设1: Timelines

Timelines预设显示了在工程编译过程中如何安排并行调用的时间。每条时间轴都代表一个虚拟线程以及有是哪项任务执行在该线程上。在多个线程上执行的调用将占用多条时间轴。

需要注意的是,仅从Visual Studio 2019版本16.4开始,才可以使用精确的并行代码生成功能。在早期版本中,给定的编译器或连接器调用的所有代码生成都是放在一条时间轴上。

查看Timelines预设时,将鼠标悬停在彩色条上可以查看其对应的调用。下图显示了将鼠标悬停在第5条时间轴上的条形上方时发生的情况。

预设2: Invocations

Invocations预设在其自己的时间轴上显示每个调用,而与并行性无关。它更详细地介绍了调用中发生的细节。使用此预设,将鼠标悬停在彩色条上会显示调用在任何时间点正在处理的活动。在下面的示例中,我们可以看到链接器调用58中的绿色条对应于整个程序的分析活动,即链接时间代码生成的一个阶段。我们还可以看到连接器调用58的输出是c2.dll。

预设3: Invocation Properties

InvocationProperties预设在视图底部的表中显示每个调用的各种属性。你可以从中找到感兴趣的调用,然后查看有关它的各种信息,例如:

>编译器或者链接器的版本。

>当前工作目录

>重要的环境变量,例如PATH或_CL_。

>编译过程中使用到的完整命令行,包括来自响应(.RSP)文件或环境变量的参数。

请注意,如果命令行或环境变量太长,则有时会在多个条目中显示它们。

预设4: Activity Statistics

ActivityStatistics预设显示BuildExplorer视图跟踪的所有工程编译活动的汇总统计信息。例如,使用它可了解所有链接器和编译器调用的总持续时间,或者判断工程的编译时间是否受到了解析或代码生成的影响。在此预设下,视图的图形部分显示每个活动的活动时间,而表格部分显示合计的持续时间总计,可以通过活动的详细信息来查看该活动的所有实例。图形,表格和下拉列表的界面如下图所示。

一个实际案例

在这个实际案例研究中,我们使用了来自GitHub的真实开源项目,并展示了如何发现并修复工程编译时间的瓶颈。

具体步骤如下:

1.搜索并[GitforWindowsGitHub]仓库到本地。

2.切换到[vs/master]分支。

3.从工程的根目录开始,打开[git\git.sln]解决方案。

4.生成x64版本配置。这将提取所有程序包依赖关系并进行一次完整的工程编译。

5.获取有关工程编译的信息:

5.1在PATH上使用vcperf打开具备管理员权限的命令提示符。

5.2运行以下命令:vcperf/startGit

5.3在VisualStudio中重新编译[x64Release]版本的[git\git.sln]解决方案。

5.4运行以下命令:vcperf/stopGitgit.etl。这将在git.etl文件中保存工程编译的所有信息。

6.在WPA中打开编译信息。

我们使用BuildExplorer视图的Timelines预设,并立即注意到了长时间运行的调用似乎是工程编译开始时的瓶颈。如下图所示:

我们查看该调用的属性,并注意命令行中没有使用到/MP编译开关,这个开关用来启用编译器的并行执行。我们还从[WorkingDirectory]属性中注意到,正在编译的项目称为[libgit]。

我们可以在VisualStudio里为工程libgit上启用/MP编译开关,如下图所示:

接下来,我们可以使用本节开头的步骤来重新捕获一次工程编译信息,以此来确认我们是否已经解决了这个编译瓶颈问题。我们发现:构建时间从大约120秒减少到80秒,编译性能提高了33%。

通过C++ Build Insights SDK来定位工程编译瓶颈

使用vcperf和WPA手动执行的大多数分析任务也可以使用C++ Build Insights SDK以程序化的方式执行。

为了说明这一点,我们准备了[BottleneckCompileFinder]SDK示例。当找到未使用/MP编译开关的编译器调用瓶颈时,它将发出警告。

如果没有其他编译器或连接器调用同时被调用,则该调用被视为瓶颈。

让我们重复上一节中的Windows版Git案例研究,但是这次通过使用BottleneckCompileFinder来查看发现的编译瓶颈。

具体步骤如下:

1. 搜索并克隆C++ Build Insights SDK示例仓库。

2. 针对所需的体系结构(x86或x64)并使用所需的配置(调试或发行版),编译Samples.sln解决方案。编译出来的可执行文件将从仓库的根目录开始放置到[out///BottleneckCompileFinder]文件夹中。

3. 按照上一章节的步骤进行操作并收集工程编译的信息。停止信息收集时,请使用[/ stopnoanalyze]命令而不是[/stop]命令。

4. 将收集的信息作为第一个参数传递给BottleneckCompileFinder可执行文件。

如下图所示,BottleneckCompileFinder可以正确识别libgit项目并发出了警告。它还标识了另一个:xdiff,尽管它对工程编译的时间影响很小而不需要采取任何改进措施。

示例代码解析

我们首先要求C++BuildInsightsSDK将我们需要的内容转发给OnStartInvocation,OnStopInvocation和OnCompilerCommandLine函数,从而过滤所有开始活动,停止活动和简单事件。函数的名称对C++BuildInsightsSDK如何过滤事件没有影响,只有它们的参数很重要。如以下代码所示:

我们的OnCompilerCommandLine函数跟踪所有不使用/MP编译开关的编译器调用。如果这些调用是瓶颈,则稍后将使用此信息来发出有关这些调用的警告。

我们的OnStartInvocation和OnStopInvocation函数通过在启动时将它们添加到哈希图中,并在停止时将其删除来跟踪并发运行的调用。一旦同时激活两个调用,我们认为所有其他调用不再是瓶颈。如果在达到停止事件后将编译器调用标记为瓶颈,则意味着在运行时再也不会启动另一个调用。如果这些调用未使用/MP编译开关,则会警告用户。

总结

小哥我目前的工程的整体编译时间不足30秒,所以,应该还不是什么大的问题。

故,以上内容,献给编译一次可以喝一杯咖啡的大佬。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200425A0QA9O00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券