Build 是thinto';并行构建系统中的并发有用吗?

Build 是thinto';并行构建系统中的并发有用吗?,build,linker,llvm,lto,Build,Linker,Llvm,Lto,我有一个构建系统,它通过-flto标志在clang中使用长期存在的LTO支持 添加到LLVM()中的ThinLTO支持看起来很有趣,但我对在已经运行并发作业的构建系统的上下文中启动std::thread::hardware\u concurrency并行处理线程的决定有点困惑 如果您有一个构建系统,它已经在为每个核心启动一个线程,并运行编译和链接作业的混合,那么链接器假设它应该使用所有核心,甚至多个核心,这是否仍然有意义 或者将ThinLTOs后台并发性降低为1,并在中记录标志,这样做有意义吗?

我有一个构建系统,它通过
-flto
标志在clang中使用长期存在的LTO支持

添加到LLVM()中的ThinLTO支持看起来很有趣,但我对在已经运行并发作业的构建系统的上下文中启动
std::thread::hardware\u concurrency
并行处理线程的决定有点困惑

如果您有一个构建系统,它已经在为每个核心启动一个线程,并运行编译和链接作业的混合,那么链接器假设它应该使用所有核心,甚至多个核心,这是否仍然有意义


或者将ThinLTOs后台并发性降低为1,并在中记录标志,这样做有意义吗?当并行性被移除时,ThinLTO比普通的旧LTO有什么优势吗?

ThinLTO实际上可以大大缩短大型项目的构建时间,还有其他好处。缓存不仅仅是为增量构建而设计的——它是多线程链接阶段工作原理的一部分,旨在加快符号查找。ThinLTO在缩短构建时间方面对您有多大帮助取决于您的项目和构建系统

我发现了一个非常好的视频,它详细介绍了ThinLTO的设计、使用案例以及成功实施的一些方法:

相应的谷歌研究论文也是一篇非常有趣(如果很重)的读物:

对于更轻松、更随意的拍摄,这篇博文也很有帮助:


我的理解是,它解决了构建过程中的链接时间瓶颈。正如您所提到的,基于My
ninja
的翻译单元编译已经并行运行,但是链接步骤是独立的。在运行任何整个程序优化之前,“传统”LTO中仍然存在将
.o
粘合在一起的瓶颈。这就是其中一个主要优势所在,即解决规模和速度问题。@compor-对于一个有大量先决编译,然后在最后一个链接步骤的链接来说,这很有意义。但是,如果有很多编译和链接,比如单元测试二进制文件,情况又如何呢。如果您与thinlto并行运行这样的构建,那么在我看来,您最终可能会得到$numpu并发链接,每个链接使用$numpu线程,这听起来像是大量的过度订阅。这是有道理的,但有点难(甚至超出范围?)为了使链接器适应这种情况,因为我们讨论的是将产生不同二进制文件的不同调用(不考虑LTO类型)。在这种情况下,我认为责任落在构建工具上,它为每个项目协调所有这些。@compor-当然,由构建系统来进行调用,并且由于我认为oversubscription参数是有效的,所以我在构建中添加了必要的
'-Wl,-plugin opt,jobs=1'
咒语。但我真正好奇的是,这样做是否能有效地完全降低
-flto=thin
相对于普通的
-flto
的优势。或者ThinLTO做其他事情,这仍然是在现代工具链中实现LTO的正确方法。如果它确实做了其他事情,而不是将并行性带到表中,那么这些事情是什么?Thinto文档对此没有多大说明,而是着重于并发性。@compor-一些进一步的想法。当我仔细研究ThinLTO设计时,另一个方面似乎是增量行为和缓存。对于交互式使用来说,这听起来很有吸引力,所以在这种情况下使用thinlto可能还是有好处的。但是对于在每次提交时都执行干净构建的CI系统,缓存可能没有用处,也可能不需要。我想知道,如果你把并行性和增量行为都去掉,在
-flto=thin
中还有什么比普通
-flto
更有价值的地方吗。研究还在继续。。。