我在每次提交时都在buildbot中编译2个C ++项目。两者都是大约1000个文件,一个是100 kloc,另一个是170 kloc。编译时间与gcc(4.4)到Visual C ++(2008)非常不同。
一个项目的Visual C ++编译需要20分钟。他们无法利用多核,因为项目依赖于另一个。最后,在Debug和Release中对32和64位的两个项目进行完整的编译需要超过2个半小时。
一个项目的gcc汇编需要4分钟。它可以在4个核心上并行化,大约需要1分10秒。 2个项目的4个版本(Debug / Release,32/64位)的所有8个版本都在不到10分钟的时间内编译完成。
Visual C ++编译时发生了什么?它们基本上慢了5倍。
编译C ++ kloc可以预期的平均时间是多少?我的是vs ++为7 s / kloc,gcc为1.4 s / kloc。
可以采取任何措施加快Visual C ++上的编译时间吗?
答案 0 :(得分:16)
减慢VC ++编译器的一件事是,如果您有一个头文件来初始化非trival const
值类型的具体实例。您可能会发现类型为std::string
或GUID的常量会发生这种情况。它会影响编译和链接时间。
对于单个dll,这导致了10倍的减速。如果将它们放在预编译的头文件中,或者只是在头文件中声明它们并在cpp文件中初始化它们会有所帮助。
请查看病毒扫描程序,并确保尝试使用预编译的标头,如果没有它,您将无法看到VC ++的最佳状态。
哦,是的,并确保%TMP%文件夹与编写构建的位置在同一分区上,因为VC ++会生成临时文件并在以后移动它们。
答案 1 :(得分:11)
彼此依赖的项目并不意味着不可能进行并行化。构建系统足够智能,可以找出并避免关键的依赖性,否则gcc将无法使用4个核心。
所以(除了其他步骤),为什么不尝试使用/ MP在Visual Studio中启用多处理(参见http://msdn.microsoft.com/en-us/library/bb385193.aspx)。
答案 2 :(得分:6)
您是如何构建Visual Studio项目的?你刚刚用项目和/build
运行ide(devenv),或者你有一个类似于我假设你用于gcc的makefile。我假设两个版本都使用类似的makefile,但我认为值得检查。
您是否正在为任一编译器使用预编译头文件?如果您没有为VS使用预编译头,那么您可能希望切换到使用它们。我个人建议使用#pragma hdrstop
方法而不是单个全包头文件,但是如果你当前没有使用预编译的头文件,并且想要尝试一个强制包含的单个全包头文件(使用/FI
编译器命令行开关)可以快速测试,无需更改任何代码。
我在这里写了/FI
和#pragma hdrstop
:http://www.lenholgate.com/blog/2004/07/fi-stlport-precompiled-headers-warning-level-4-and-pragma-hdrstop.html
答案 3 :(得分:6)
这不是问题的直接答案,但在我的公司,我们使用IncrediBuild进行分布式编译。它确实加快了编译过程。 http://incredibuild.com/visual_studio.htm
答案 4 :(得分:3)
John Lakos撰写的“大规模C ++软件设计”一书提供了许多关于为大型项目构建代码和设计的技巧。包括许多关于加速编译的技巧。与Visual C ++没有直接关系,但无论如何都值得一读。
答案 5 :(得分:2)
我写了两篇关于减少编译时间的技术的文章。在这些技术中,precompiled header和unity builds上的帖子可以帮助您缩短编译时间。它们附带了CMake脚本,可以透明地处理这些技术。
答案 6 :(得分:1)
首先,在大多数情况下,您可以并行构建同一项目的调试和发布配置。
你所描述的内容听起来也非常慢 - 看起来你没有在VC ++中使用预编译头文件或者使用它们不正确 - 它们专门用于缩短编译时间。
答案 7 :(得分:1)
可能存在依赖项检查的问题,除非您强制进行完全重建。
你可以创建一些静态库。将很少更改的代码放入库中。
构建程序的最慢部分:
通常,链接和可执行文件创建阶段是最快的。
你确定了:
请记住,在确定效率时,请始终(以某种方式)。
答案 8 :(得分:0)
你在同一台机器上建造吗?你使用相同的操作系统吗?我在Cygwin中比较GCC和在Windows主机Cygwin中运行的VirtualBox机器中的GCC时,看到了3-10倍的速度差异。
答案 9 :(得分:0)
似乎很奇怪会有这样的差异......但是没有理由你不能利用Visual上的多核......
基本上你有4种编译模式:(调试/发布)x(32位/ 64位),每一种都完全独立于另一种模式,你可以完美地并行运行4,充分利用4个核心。或者只是在Visual Studio上尝试使用MultiProcessor方法。
然而,这不会削减它。 150分钟对10分钟是一个巨大的差距。根据我的个人经验,减少编译时间有两个主要因素:
答案 10 :(得分:0)
一次编译并链接一个cpp文件,即使header-file-changes影响多个cpp文件也是如此。这可以通过visual studio macro实现:
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
答案 11 :(得分:0)
不知道这是否仍然存在问题以及你在menatime中获得了多少改进,但是如果它仍然存在,msbuild不知道如何在一个项目中同时编排(每个cpp应该是可单独构建的,除非你有一些代码 - 代码最好转移到一个单独的项目)你必须下载驱动程序开发工具包或.NET SSCLI,因为他们都有nmake,build已知可以很好地兼容事物。 SSCLI已经有了构建版本设置,不记得DDK是否有一些构建样本,你必须从头开始。
还有点旧的article on MSBuild并行化没有详细说明,但提到了实际的msbuild和msbuild + sln之间的一些差异。如果/ MP vs. / Gm是唯一的问题,那么你可能需要制作一个小脚本或C#exe来编辑实验室版本的.proj文件。或者在项目中使用显式cmd行覆盖,并从env var。
中获取该选项