加快增量开发者构建方案

[原文发表地址] VisualC++ Team Blog ->Speeding up the Incremental Developer Build Scenario

[原文发表时间 ] 2014/11/12 3:35PM

概述

Visual C++的主要关注领域之一是不断提高开发人员的生产率。牢记于此,很多的改进旨在开发者增量场景已经被引入了Visual Studio 2015 preview(下载点击这里)。增量开发者方案指的是,开发人员修改了单个或多个源文件(在修复bug的时候),再构建。这种构建方案对于Visual C ++来说大致相当于一次链接便携式可执行文件(.dll 或 .exe )花费的时间。当然正在这篇文章中讨论这种功能大多运用在链接器空间。 

在链接器空间的新增功能,平均而言,我们已经看到了大约2倍提高简洁链接的情况,并增加了更多的方案,包括现在可以增量链接或增量代码生成(当使用链接时代码生成(LTCG)
)。下面总结了这些功能集以及如何使他们并附于下表,但如果你有兴趣了解更多关于这些功能的话,请继续沿着下面的部分阅读。 

 

特性

描述

组态

用法

静态库的增量链接

增量连接当编辑被其他可携带执行文件调用的静态库(.dll 或者.exe)

影响所有除了LTCG启用构建

默认情况下启用时(/incremental)链接器开关。

/Debug:FastLink

调试时获得快速的链路吞吐量生成新的程序数据库(PDB)文件。

影响所有除了LTCG启用构建。

/Debug:FASTLINK(链接器开关)

/Zc:inline和算法的改进

编译器不再为死代码生成符号信息。

影响所有除了LTCG启用构建。

/ ZC:inline(编译器开关)

增量LTCG     (仅目标机器为x86)

当LTCG启用工作基础之上,启用增量代码生成。

仅影响LTCG建立。

/ LTCG:incremental(linker switch)

       
          表1:在VS2015preview推出的功能,为了加快增量开发方案

 

静态库的增量链接 / incremental linker switch)

从我们的数据分析报告得出增量链接失败其中一个最主要原因的是,当一个开发人员对静态库做出修改,并编译文件调用它。当我们开始努力时,我们看了一下在Xbox One平台上内部正在开发的各种游戏,它已经变得很清楚了,为什么我们需要支持这种方案。如果你要在Visual Studio中打开一个“Kinect运动对手(KSR)”第一方标题的解决方案会让你们了解这一方案。你会发现最终构建调试配置时,大量的“Kinect运动对手”可执行文件大约使用了70的静态库项目,以及1.8G大小的PDB。随着Visual Studio 2015preview在KSR的开发人员现在终于可以利用增量链接,这就说明它可以支持编辑静态库。

/ ZC :内联和算法的改进(/ ZC:inline 编译器开关,2X更快的链接)

/ ZC:inline 在之前的博客已经谈到了,但回顾一下,打开此开关指示编译器不再为未引用的数据和函数生成符号。这不仅导致目标文件更小,而且减少的输入使连接器减少连接次数。随着/ ZC:inline开关和其他算法在游戏上的改进,如下图所示,你可从看到简洁式链接为“Kinect运动对手”链接次数的降低。一些其他流行的基准平台也从中受益,如(Chrome,Xbox游戏),而另一些,由于法律上的原因,不能在这里讨论。作为一个忠告,请记住,/ ZC:inline开关只影响优化(非/ Od和非LTCG)构建。                 

      

图1:使用/Zc:inline简洁式链接次数

 

快速的程序数据库( PDB )生成(/debug:FASTLINK链接器开关,2X更快的链接),
Visual C ++的链接器对非LTCG构建其大部分时间花费在生成程序数据库文件(PDB)。合并类型的信息,固定了私有符号的类型索引,还有生成全局符号都是PDB生成时间主要组成部分。随着/ DEBUG:FASTLINK链接产生PDB没有任何私有的符号,和调试信息分布在输入对象和库文件,链接器生成PDB只是作为一个索引数据库。DIA API已被修改,以(仅)用于调试提供无缝体验,并使用这个选项提供更快的链接次数,并且很少或根本不会影响到整体调试体验。为了进一步说明这一点,我们在实验室里对其他几个基准和使用/DEBUG:FASTLINK 链接次数下降的对比。 

      

                          
      图2:简洁链接次数/debug:fastlink 

 

增量链接时间代码生成( iLTCG / LTCG incremental linker switch, 4X快的链接)

链接时代码生成(AKA全程序优化)产生更好质量的代码,因为我们有额外的对整个程序的优化,进一步优化的代码,影响整个程序的描述,但它唯一在LTCG链接可用。LTCG在生成代码质量方面很棒,这是Pogo的基础; 但吞吐量是其缺点,如今的开发者也不得不等待全面简洁LTCG编译次数甚至微不足道的修改。这往往成为这个功能的普及主要障碍,当今的开发人员只能被迫放弃这些额外的性能提高,而倾向于提高生产率的改进。

LTCG的工作原理是这样的, 整个程序分析结果被用于优化,程序中任何函数的任何改变都可能会影响其他不同模块中一个不相关的函数的代码生成或者功能优化。因此,只要整个程序有任何改变,包括一些未改变的模块,我们都需要重新编译整个程序。为了提高LTCG的吞吐量,同时保持它对代码质量的优点,我们引入了增量LTCG。利用增量LTCG,我们能够捕捉到一个修改对整个程序的优化效果精确的影响,仅仅重新编译受影响的函数。对于那些未受影响,我们直接从以前的编译器的输出复制其代码,从而减少构建时间而不牺牲代码的质量。当修改是微不足道的时候,从iLTCG吞吐量的改善可高达4倍。只是为了说明这一点,下图中,您将看到由我们自己的编译器后端开发人员构建编译器后端(c2.dll),通过使用84个真正的合入测量的构建吞吐量增加。平均而言,用这种方案观察到大约3.6倍加速。总体来说我们已经看到在生成代码的微小影响(<我们的基准0.5%CQ损失),但在LTCG上的构建改善了很多。我们的目标是始终启用此功能及时外部转移产品。 

       
                       

图4:编译器后端(c2.dll)使用增量LTCG的吞吐量增长

 

 

下一步是什么?

然而,对我们来说,增量开发构建方案仍然是一个具有争议的方案,我们也做了改善简洁构建次数,通常大部分时间都用在编译器前端的工作。这项示范工作的结果是大量的C ++代码现在应该编译的更快。举一个例子,虚幻游戏引擎,它是利用VS2015预览模板重编译速度将提高大约30%。然而不幸的是,我们也看到了一些倒退被引入,当我们迈进预览主要是由于新的一致性功能。这些退化正在被跟踪和在下一步开发中解决。   

 

特此声明

这个博客应该给你概述了关于我们在VS2015preview改善开发的增量情况所做的工作。我们目前的重点是观察稍大的项目,并因此使大型项目能够关注我们取得的这些技术改进,如Chrome或其他的等。请给他们一个展示,让我们知道它是如何为你的应用工作。如果你们尝试这些功能的时候,并发布有关链接吞吐量前/后的数字,这将是最棒的。如果你是链接仍然十分缓慢,或者您正在寻找更多的反馈意见,请发邮件给我,ANKIT,在 aasthan@microsoft.com。我们很想了解更多!

感谢谷歌浏览器的开发人员和Kinect运动对手团队的验证,我们的改变在现实世界的情景产生了积极的影响。

 

Announcement