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

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

要回复问题请先登录注册