如何改进Visual C ++编译时间?

时间:2010-02-12 10:51:18

标签: c++ visual-c++ gcc comparison compilation-time

我在每次提交时都在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 ++上的编译时间吗?

12 个答案:

答案 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 hdrstophttp://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 headerunity builds上的帖子可以帮助您缩短编译时间。它们附带了CMake脚本,可以透明地处理这些技术。

答案 6 :(得分:1)

首先,在大多数情况下,您可以并行构建同一项目的调试和发布配置。

你所描述的内容听起来也非常慢 - 看起来你没有在VC ++中使用预编译头文件或者使用它们不正确 - 它们专门用于缩短编译时间。

答案 7 :(得分:1)

可能存在依赖项检查的问题,除非您强制进行完全重建。

你可以创建一些静态库。将很少更改的代码放入库中。

构建程序的最慢部分:

  1. 打开和关闭文件。
  2. 解析和翻译源代码 文件。
  3. 通常,链接和可执行文件创建阶段是最快的。

    你确定了:

    1. 哪个阶段最慢?
    2. 哪些文件编译速度最慢?
    3. 请记住,在确定效率时,请始终(以某种方式)。

答案 8 :(得分:0)

你在同一台机器上建造吗?你使用相同的操作系统吗?我在Cygwin中比较GCC和在Windows主机Cygwin中运行的VirtualBox机器中的GCC时,看到了3-10倍的速度差异。

答案 9 :(得分:0)

似乎很奇怪会有这样的差异......但是没有理由你不能利用Visual上的多核......

基本上你有4种编译模式:(调试/发布)x(32位/ 64位),每一种都完全独立于另一种模式,你可以完美地并行运行4,充分利用4个核心。或者只是在Visual Studio上尝试使用MultiProcessor方法。

然而,这不会削减它。 150分钟对10分钟是一个巨大的差距。根据我的个人经验,减少编译时间有两个主要因素:

  • 在本地磁盘上使用所有文件(如果需要,使用远程复制)和本地创建的所有文件(.o .so)
  • 使用您可以使用的所有核心,如果可以,甚至可以使用Multi Machines(distcc等...)

答案 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。

中获取该选项