如何提高Visual C ++编译时间?
我在buildbot中编译2个C ++项目,每次提交。 两者都是大约1000个文件,一个是100kloc,另一个是170kloc。 编译时间与gcc(4.4)到Visual C ++(2008)非常不同。
一个项目的Visual C ++编译在20分钟内完成。 他们不能利用多核心,因为一个项目依赖于另一个。 最后,debugging和发布中的32位和64位两个项目的完整编译需要超过2个半小时。
一个项目的gcc编译在4分钟内完成。 它可以在4个核心上并行,大约需要1分10秒。 两个项目的4个版本(debugging/发布,32/64位)的所有8个版本都在不到10分钟的时间内编译完成。
Visual C ++编译时间发生了什么? 他们基本上慢了5倍。
预计编译C ++ kloc的平均时间是多less? 我的vc ++为7s / kloc,gcc为1.4s / kloc。
可以做任何事情来加快Visual C ++编译时间?
减慢VC ++编译器的一件事情是,如果你有一个头文件来初始化非trival const
值types的具体实例。 您可能会看到types为std::string
或GUID的常量发生这种情况。 它影响编译和链接时间。
对于一个单一的DLL,这导致了10倍的放缓。 如果你把它们放在一个预编译的头文件中,或者只是将它们声明在一个头文件中,并将它们初始化为一个cpp文件,这会有所帮助。
看看病毒扫描程序,并确保试验预编译头,没有它,你将不会看到最好的VC ++。
哦,是的,并确保%TMP%文件夹是在您的构build写入到相同的分区,因为VC + +生成临时文件,并稍后移动它们。
相互依赖的项目并不意味着并行化是不可能的。 构build系统足够聪明,可以计算出并避免关键的依存关系,否则gcc将无法使用4个内核。
所以(除了其他步骤),为什么不尝试使用/ MP在Visual Studio中启用多处理(请参阅http://msdn.microsoft.com/zh-cn/library/bb385193.aspx )。
这不是问题的直接答案,但在我的公司,我们使用IncrediBuild进行分布式编译。 它确实加快了编译过程。 http://incredibuild.com/visual_studio.htm
你如何构buildVisual Studio项目? 你只是运行ide(devenv)与项目和/build
或者你有一个makefile类似于我认为你正在使用的gcc。 我假设这两个版本使用类似的生成文件,但我认为这值得检查。
你是否使用编译器的预编译头? 如果你没有使用VS的预编译头文件,那么你可能想切换到使用它们。 就个人而言,我build议使用#pragma hdrstop
方法,而不是一个全包的头文件,但如果你目前不使用预编译的头文件,并希望尝试一个包含力量的全包头文件(使用/FI
编译器命令行开关)可以快速testing而不需要任何代码改变。
我在这里写了/FI
和#pragma hdrstop
: http : //www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html
John Lakos所写的“大规模C ++软件devise”一书在构build大规模项目代码和devise方面有很多技巧。 包括加速编译的许多提示。 与Visual C ++没有直接关系,但是值得一读。
我写了两篇关于减less编译时间的技巧。 在这些技术中, 预编译头文件和统一编译可以帮助您改进编译时间。 它们附带CMake脚本,透明地处理这些技术。
首先,在大多数情况下,您可以并行构build相同项目的debugging和发布configuration。
另外你所描述的听起来非常慢 – 看起来你不使用VC ++中的预编译头文件或不正确地使用它们 – 它们专门用于提高编译时间。
也许有一个依赖检查的问题,除非你强迫一个完整的重build。
你可以做一些静态库。 把很less改变的代码放到库中。
build设项目最慢的部分:
- 打开和closures文件。
- 分析和翻译源文件。
一般来说,链接和可执行的创build阶段是最快的。
你有没有确定:
- 哪个阶段最慢?
- 哪些文件最慢编译?
请记住,在确定效率的时候,总是以某种方式进行分析。
你在同一台机器上build造吗? 你使用相同的操作系统? 在Cygwin和GCC中,在Cygwin的Windows主机中运行的VirtualBox机器上比较GCC时,我发现3-10x的速度差异。
看起来很奇怪,会有这样的区别…但是没有理由不能利用视觉上的多核。
基本上你有4种编译模式(debugging/释放)x(32位/ 64位),每一个都完全独立于另一个,你可以完美地并行运行4个,充分利用4个可用的内核。 或者只是简单地尝试Visual Studio的MultiProcessor方法。
但是,这不会削减它。 150分钟对比10分钟是一个巨大的差距。 从我个人的经验来看,减less编译时间有两个主要因素:
- 拥有本地磁盘上使用的所有文件(如果需要,使用远程复制)以及本地创build的所有文件(.o .so)
- 使用所有的核心在你的处置,如果可以的话,甚至去多机(distcc等…)
一次编译并链接一个cpp文件 ,即使头文件更改影响多个cpp文件也是如此。 这可以通过Visual Studiomacros来实现:
Dim WithEvents myTimer As Timers.Timer Sub CompileAndLinkCurrentCppFile() DTE.ExecuteCommand("Build.Compile") myTimer = New Timers.Timer myTimer.Interval = 0.05 myTimer.Start() End Sub Sub myTimer_Elapsed(ByVal ee As Object, ByVal dd As Timers.ElapsedEventArgs) Handles myTimer.Elapsed If DTE.Solution.SolutionBuild.BuildState <> vsBuildState.vsBuildStateInProgress And DTE.Solution.SolutionBuild.LastBuildInfo <> 1 Then myTimer.Stop() DTE.ExecuteCommand("Build.Link") End If End Sub
不知道这是否仍然是一个问题,你在menatime得到了多less改进,但是如果现在仍然认为msbuild不知道如何在一个项目中同时进行编排(每个cpp都应该单独构build,除非你有一些代码- codegens最好转移到一个单独的项目),你必须下载驱动程序开发工具包或.NET SSCLI,因为他们都有nmake,build立已知的协调好事情。 SSCLI已经有了构build版本的设置,不要记得DDK是否有一些构build样本,你必须从头开始。
MSBuild并行化方面有点古老的文章也没有涉及细节,但提到了实际的msbuild和msbuild + sln之间的差异。 如果/ MP与/ Gm是唯一的问题,那么你可能不得不做一个小脚本或C#EXE编辑实验室构build.proj文件。 或者在项目中使用显式的cmd行覆盖,并从env var中获取该选项。