对于开发人员场景,链接占据了应用程序构建时间的大部分。从我们的调查中,我们知道Visual C++链接器在准备、合并和最终写入调试信息方面花费了大量的时间。这对于非专业人士尤其如此- 全程序优化 情节。
在 Visual Studio 2013更新2 CTP2 ,我们添加了一组有助于显著提高链接时间的功能,这些功能通过我们在实验室构建的产品(AAA游戏和开源项目,如Chromium)来衡量:
- 删除未引用的数据和函数 ( /Zc:内联 ). 这可以帮助你的所有项目。
- 减少生成PDB文件所花费的时间 . 这主要适用于具有中到大量调试信息的二进制文件。
- 并行化代码生成和优化构建阶段 ( /CG线程 ). 这适用于通过LTCG生成的中大型二进制文件。
默认情况下,并非所有这些功能都已启用。继续阅读更多细节。
删除未引用的数据和函数(/Zc:inline)
作为我们分析的一部分,我们发现,即使对于未引用的函数和数据,我们也不一定会因为发出符号信息而膨胀对象文件的大小。因此,这将导致对链接器的额外和无用的输入,这些输入最终将由于链接器优化而被丢弃。
应用 /Zc:内联 在编译器命令行上,将导致编译器执行这些优化,从而减少链接器的输入,提高端到端链接器的吞吐量。
新编译器开关: /Zc:内联[-] –删除未引用的函数或数据(如果它是COMDAT或只有内部链接)(默认情况下关闭)
吞吐量影响: 显著的(两位数(%)链接改进,在构建铬等产品时可以看到)
突变: 是的(可能)对于不符合代码(用C++ 11标准),打开这个功能可能意味着在某些情况下,你会看到一个未解决的外部符号错误,如下所示,但是解决方法非常简单。请看下面的示例:
如果您使用的是VS2013 RTM,那么这个示例程序将编译( cl/O2 x.cpp x流量.cpp )并成功链接。但是,如果编译并链接到VS2013,请使用 /Zc:内联 已启用( cl/O2/Zc:内联x.cpp xfunc.cpp ),示例将阻塞并产生以下错误消息:
xfunc.obj : error LNK2019: unresolved external symbol "public: void __thiscall x::xfunc1(void)" (?xfunc1@x@@QAEXXZ) referenced in function _main x.exe : fatal error LNK1120: 1 unresolved externals
有三种方法可以解决这个问题。
- 从函数“xfunc”的声明中删除“inline”关键字。
- 将函数“xfunc”的定义移到头文件“x.h”中。
- 只需在xfunc.cpp中包含“x.cpp”。
适用性: 除了 LTCG/WPO公司 一些(调试)场景应该会看到显著的加速。
减少生成PDB文件所花费的时间
该特性通过增加内部数据结构(哈希表等)的大小来显著提高类型合并速度。对于更大的PDB,这将最多增加几MB的大小,但可以显著减少链接时间。现在,默认情况下启用了此功能。
吞吐量影响: 重大(AAA游戏的两位数(%)链接改进)
突变: 不
适用性: 除了 LTCG/WPO公司 在这种情况下,速度应该会大大加快。
并行化代码生成和优化构建阶段(/cgthreads)
该特性(通过多个线程)并行化编译过程的代码生成和优化阶段。今天的默认情况下,我们在codegen和优化阶段使用四个线程。随着机器资源越来越丰富(CPU、IO等),拥有一些额外的构建线程不会有什么坏处。此功能在执行 全程序优化(WPO) 建造。
已经有多个级别的并行性可以用于构建工件。这个 /米 或 /最大计数 指定可以并行运行的msbuild.exe进程数。在哪里,作为 /MP公司 或多进程编译器标志指定可以同时编译源文件的cl.exe进程数。
这个 /CG线程 flag添加了另一个并行级别,其中它指定了用于每个cl.exe进程的代码生成和优化阶段的线程数。如果 /CG线程 , /MP公司 和 /米 如果设置得太高,很可能会使构建系统崩溃,使其无法使用,因此 慎用 !
新编译器开关: /CG螺纹编号 ,其中N是用于优化和代码生成的线程数N’表示线程数,’N’可以在[1-8]之间指定。
突变: 没有,但是这个开关现在 不支持 但我们正在考虑将其作为一个受支持的功能,因此您的反馈非常重要!
适用性: 这应该会对 全程序优化 情节。
包装
这个博客应该给你一个关于我们在最新CTP中启用的一组功能的概述,这些功能应该有助于提高链路吞吐量。我们目前的重点是看目前稍大的项目,因此这些胜利应该是最引人注目的大型项目,如Chrome和其他。
请给他们一个机会,让我们知道你的申请结果如何。这将是伟大的,如果你们可以张贴之前/之后的数字链接器吞吐量时,尝试这些功能。
如果你是链接时间仍然是痛苦的缓慢,请给我发电子邮件,安基特,在 aasthan@microsoft.com . 我们很想知道更多!
感谢C++ MVP Bruce Dawson,铬开发者和Kinect运动对手团队,以验证我们的变化在现实场景中有积极的影响。