I recently had cause to work with some Visual Studio C++ projects with the usual Debug and Release configurations, but also 'Release All' and 'Debug All', which I had never seen before.
最近,我有理由使用一些Visual Studio c++项目,使用常规的调试和发布配置,但同时也“释放所有”和“调试所有”,这是我以前从未见过的。
It turns out the author of the projects has a single ALL.cpp which #includes all other .cpp files. The *All configurations just build this one ALL.cpp file. It is of course excluded from the regular configurations, and regular configurations don't build ALL.cpp
事实证明,这些项目的作者只有一个“全部”。cpp,其中#包含所有其他的。cpp文件。所有的配置都构建了这个。cpp文件。它当然被排除在常规配置之外,常规配置不会构建全部。cpp
I just wondered if this was a common practice? What benefits does it bring? (My first reaction was that it smelled bad.)
我只是想知道这是不是一种常见的做法?它能带来什么好处?(我的第一反应是闻起来很难闻。)
What kinds of pitfalls are you likely to encounter with this? One I can think of is if you have anonymous namespaces in your .cpps, they're no longer 'private' to that cpp but now visible in other cpps as well?
你可能会遇到哪些陷阱?我能想到的一个问题是,如果.cpps中有匿名名称空间,那么cpp将不再是私有的,但其他cpps中也可以看到这些名称空间吗?
All the projects build DLLs, so having data in anonymous namespaces wouldn't be a good idea, right? But functions would be OK?
所有项目都构建dll,因此在匿名名称空间中拥有数据不是一个好主意,对吗?但是函数是可以的?
Cheers.
欢呼。
5 个解决方案
#1
49
It's referred to by some (and google-able) as a "Unity Build". It links insanely fast and compiles reasonably quickly as well. It's great for builds you don't need to iterate on, like a release build from a central server, but it isn't necessarily for incremental building.
它被一些人(也可以用谷歌搜索)称为“统一构建”。它的链接速度快,而且编译速度也相当快。这对于构建您不需要迭代的构建非常好,就像从*服务器构建版本一样,但它并不一定用于增量构建。
And it's a PITA to maintain.
这是一个需要维护的皮塔。
EDIT: here's the first google link for more info: http://buffered.io/posts/the-magic-of-unity-builds/
编辑:这里是第一个关于更多信息的谷歌链接:http://bufferedio/posts/the magic-of-建站/
The thing that makes it fast is that the compiler only needs to read in everything once, compile out, then link, rather than doing that for every .cpp file.
使它快速的是编译器只需要读取所有文件一次,编译,然后链接,而不是对每个.cpp文件都这样做。
Bruce Dawson has a much better write up about this on his blog: http://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/
布鲁斯·道森(Bruce Dawson)在他的博客上有一个更好的记录:http://randomascii.wordpress.com/2014/03/22/make-vc-compile -fast-through-parallel- compile /
#2
42
Unity builds improved build speeds for three main reasons. The first reason is that all of the shared header files only need to be parsed once. Many C++ projects have a lot of header files that are included by most or all CPP files and the redundant parsing of these is the main cost of compilation, especially if you have many short source files. Precompiled header files can help with this cost, but usually there are a lot of header files which are not precompiled.
Unity构建改进的构建速度有三个主要原因。第一个原因是所有共享头文件只需要解析一次。许多c++项目有很多头文件,这些头文件包含在大多数或全部CPP文件中,冗余的解析是编译的主要成本,特别是如果您有许多短源文件的话。预编译头文件可以帮助解决这个问题,但是通常有很多头文件没有预编译。
The next main reason that unity builds improve build speeds is because the compiler is invoked fewer times. There is some startup cost with invoking the compiler.
unity构建提高构建速度的下一个主要原因是编译器被调用的次数更少。在调用编译器时,有一些启动成本。
Finally, the reduction in redundant header parsing means a reduction in redundant code-gen for inlined functions, so the total size of object files is smaller, which makes linking faster.
最后,减少冗余头解析意味着减少内联函数的冗余代码生成,因此对象文件的总大小更小,这使得链接速度更快。
Unity builds can also give better code-gen.
统一构建也可以提供更好的代码生成。
Unity builds are NOT faster because of reduced disk I/O. I have profiled many builds with xperf and I know what I'm talking about. If you have sufficient memory then the OS disk cache will avoid the redundant I/O - subsequent reads of a header will come from the OS disk cache. If you don't have enough memory then unity builds could even make build times worse by causing the compiler's memory footprint to exceed available memory and get paged out.
Unity构建不会因为减少了磁盘I/O而更快。我已经用xperf分析了许多构建,我知道我在说什么。如果您有足够的内存,那么OS磁盘缓存将避免冗余的I/O—头的后续读取将来自OS磁盘缓存。如果您没有足够的内存,那么unity构建甚至会导致编译器的内存占用超过可用内存并被分页,从而使构建时间变得更糟糕。
Disk I/O is expensive, which is why all operating systems aggressively cache data in order to avoid redundant disk I/O.
磁盘I/O非常昂贵,这就是为什么所有操作系统都积极地缓存数据,以避免冗余磁盘I/O。
#3
6
I wonder if that ALL.cpp is attempting to put the entire project within a single compilation unit, to improve the ability for the compiler to optimize the program for size?
我想知道这一切。cpp试图将整个项目放在一个编译单元中,以提高编译器优化程序大小的能力。
Normally some optimizations are only performed within distinct compilation units, such as removal of duplicate code and inlining.
通常,一些优化只在不同的编译单元中执行,例如删除重复的代码和内联。
That said, I seem to remember that recent compilers (Microsoft's, Intel's, but I don't think this includes GCC) can do this optimization across multiple compilation units, so I suspect that this 'trick' is unneccessary.
话虽如此,我似乎还记得最近的编译器(微软的、英特尔的,但我不认为这包括GCC)可以跨多个编译单元进行这种优化,因此我怀疑这种“技巧”是不必要的。
That said, it would be curious to see if there is indeed any difference.
话虽如此,我们很想知道是否真的有什么不同。
#4
2
I agree with Bruce; from my experience I had tried implementing the Unity Build for one of my .dll projects which had a ton of header includes and lots of .cpps; to bring down the overall Compilation time on the VS2010(had already exhausted the Incremental Build options) but rather than cutting down the Compilation time, I ran out of memory and the Build not even able to finish the Compilation.
我同意布鲁斯;根据我的经验,我曾尝试为我的一个.dll项目实现Unity构建,该项目包含大量的header包含和大量的.cpps;为了降低VS2010上的总体编译时间(已经耗尽了增量构建选项),我没有减少编译时间,而是耗尽了内存,构建甚至无法完成编译。
However to add; I did find enabling the Multi-Processor Compilation option in Visual Studio quite helps in cutting down the Compilation time; I am not sure if such an option is available across other platform compilers.
然而添加;我确实发现在Visual Studio中启用多处理器编译选项有助于减少编译时间;我不确定在其他平台编译器中是否有这样的选项。
#5
0
In addition to Bruce Dawson's excellent answer the following link brings more insights onto the pros and cons of unity builds - https://github.com/onqtam/ucm#unity-builds
除了Bruce Dawson的出色回答,下面的链接还将带来更多关于unity的优点和缺点的见解——https://github.com/onqtam/ucm# unitybuild。
#1
49
It's referred to by some (and google-able) as a "Unity Build". It links insanely fast and compiles reasonably quickly as well. It's great for builds you don't need to iterate on, like a release build from a central server, but it isn't necessarily for incremental building.
它被一些人(也可以用谷歌搜索)称为“统一构建”。它的链接速度快,而且编译速度也相当快。这对于构建您不需要迭代的构建非常好,就像从*服务器构建版本一样,但它并不一定用于增量构建。
And it's a PITA to maintain.
这是一个需要维护的皮塔。
EDIT: here's the first google link for more info: http://buffered.io/posts/the-magic-of-unity-builds/
编辑:这里是第一个关于更多信息的谷歌链接:http://bufferedio/posts/the magic-of-建站/
The thing that makes it fast is that the compiler only needs to read in everything once, compile out, then link, rather than doing that for every .cpp file.
使它快速的是编译器只需要读取所有文件一次,编译,然后链接,而不是对每个.cpp文件都这样做。
Bruce Dawson has a much better write up about this on his blog: http://randomascii.wordpress.com/2014/03/22/make-vc-compiles-fast-through-parallel-compilation/
布鲁斯·道森(Bruce Dawson)在他的博客上有一个更好的记录:http://randomascii.wordpress.com/2014/03/22/make-vc-compile -fast-through-parallel- compile /
#2
42
Unity builds improved build speeds for three main reasons. The first reason is that all of the shared header files only need to be parsed once. Many C++ projects have a lot of header files that are included by most or all CPP files and the redundant parsing of these is the main cost of compilation, especially if you have many short source files. Precompiled header files can help with this cost, but usually there are a lot of header files which are not precompiled.
Unity构建改进的构建速度有三个主要原因。第一个原因是所有共享头文件只需要解析一次。许多c++项目有很多头文件,这些头文件包含在大多数或全部CPP文件中,冗余的解析是编译的主要成本,特别是如果您有许多短源文件的话。预编译头文件可以帮助解决这个问题,但是通常有很多头文件没有预编译。
The next main reason that unity builds improve build speeds is because the compiler is invoked fewer times. There is some startup cost with invoking the compiler.
unity构建提高构建速度的下一个主要原因是编译器被调用的次数更少。在调用编译器时,有一些启动成本。
Finally, the reduction in redundant header parsing means a reduction in redundant code-gen for inlined functions, so the total size of object files is smaller, which makes linking faster.
最后,减少冗余头解析意味着减少内联函数的冗余代码生成,因此对象文件的总大小更小,这使得链接速度更快。
Unity builds can also give better code-gen.
统一构建也可以提供更好的代码生成。
Unity builds are NOT faster because of reduced disk I/O. I have profiled many builds with xperf and I know what I'm talking about. If you have sufficient memory then the OS disk cache will avoid the redundant I/O - subsequent reads of a header will come from the OS disk cache. If you don't have enough memory then unity builds could even make build times worse by causing the compiler's memory footprint to exceed available memory and get paged out.
Unity构建不会因为减少了磁盘I/O而更快。我已经用xperf分析了许多构建,我知道我在说什么。如果您有足够的内存,那么OS磁盘缓存将避免冗余的I/O—头的后续读取将来自OS磁盘缓存。如果您没有足够的内存,那么unity构建甚至会导致编译器的内存占用超过可用内存并被分页,从而使构建时间变得更糟糕。
Disk I/O is expensive, which is why all operating systems aggressively cache data in order to avoid redundant disk I/O.
磁盘I/O非常昂贵,这就是为什么所有操作系统都积极地缓存数据,以避免冗余磁盘I/O。
#3
6
I wonder if that ALL.cpp is attempting to put the entire project within a single compilation unit, to improve the ability for the compiler to optimize the program for size?
我想知道这一切。cpp试图将整个项目放在一个编译单元中,以提高编译器优化程序大小的能力。
Normally some optimizations are only performed within distinct compilation units, such as removal of duplicate code and inlining.
通常,一些优化只在不同的编译单元中执行,例如删除重复的代码和内联。
That said, I seem to remember that recent compilers (Microsoft's, Intel's, but I don't think this includes GCC) can do this optimization across multiple compilation units, so I suspect that this 'trick' is unneccessary.
话虽如此,我似乎还记得最近的编译器(微软的、英特尔的,但我不认为这包括GCC)可以跨多个编译单元进行这种优化,因此我怀疑这种“技巧”是不必要的。
That said, it would be curious to see if there is indeed any difference.
话虽如此,我们很想知道是否真的有什么不同。
#4
2
I agree with Bruce; from my experience I had tried implementing the Unity Build for one of my .dll projects which had a ton of header includes and lots of .cpps; to bring down the overall Compilation time on the VS2010(had already exhausted the Incremental Build options) but rather than cutting down the Compilation time, I ran out of memory and the Build not even able to finish the Compilation.
我同意布鲁斯;根据我的经验,我曾尝试为我的一个.dll项目实现Unity构建,该项目包含大量的header包含和大量的.cpps;为了降低VS2010上的总体编译时间(已经耗尽了增量构建选项),我没有减少编译时间,而是耗尽了内存,构建甚至无法完成编译。
However to add; I did find enabling the Multi-Processor Compilation option in Visual Studio quite helps in cutting down the Compilation time; I am not sure if such an option is available across other platform compilers.
然而添加;我确实发现在Visual Studio中启用多处理器编译选项有助于减少编译时间;我不确定在其他平台编译器中是否有这样的选项。
#5
0
In addition to Bruce Dawson's excellent answer the following link brings more insights onto the pros and cons of unity builds - https://github.com/onqtam/ucm#unity-builds
除了Bruce Dawson的出色回答,下面的链接还将带来更多关于unity的优点和缺点的见解——https://github.com/onqtam/ucm# unitybuild。