我正在使用g ++来编译和链接一个包含大约15个c ++源文件和4个共享对象文件的项目。最近链接时间增加了一倍多,但我没有makefile的历史可供我使用。有没有办法分析g ++以查看链接的哪个部分需要很长时间?
编辑:在我注意到makefile一直在使用-O3优化后,我设法将删除该开关的时间缩短了一半。有没有什么好方法可以在没有反复试验的情况下找到这个?
编辑:我真的不想分析ld是如何工作的。我很想知道如何匹配特定命令行开关或目标文件的链接时间增加。
答案 0 :(得分:2)
如果您刚刚达到RAM限制,您可能会听到磁盘工作,系统活动监视器会告诉您。但是,如果链接仍然受CPU限制(即,如果CPU使用率仍然很高),那不是问题。如果链接是IO绑定的,最常见的罪魁祸首可能是运行时信息。无论如何,请查看可执行文件大小。
以不同的方式回答您的问题:您是否正在使用大量模板?对于具有不同类型参数的模板的每次使用,都会生成整个模板的新实例,因此您可以为链接器获得更多工作。但是,为了使其真正引人注目,您需要使用一些非常重的模板库。很多来自Boost项目的人都有资格 - 当使用具有复杂语法的Boost :: Spirit时,我得到了基于模板的代码膨胀。大约4000行代码编译成7,7M可执行文件 - 改变一行所需的专业数量和最终可执行文件的大小翻了一番。然而,内联帮助了很多,导致了1,900万的输出。
共享库可能会导致其他问题,您可能需要查看-fvisibility = hidden的文档,无论如何它都会改进您的代码。从GCC手册获取 - 可见性:
Using this feature can very substantially improve linking and load times of shared object libraries, produce more optimized code, provide near-perfect API export and prevent symbol clashes. It is *strongly* recommended that you use this in any shared objects you distribute.
实际上,链接器通常必须支持应用程序或其他库覆盖定义到库中的符号的可能性,而通常这不是预期的用法。请注意,使用它并非免费,但它确实需要(微不足道的)代码更改。
文档建议的链接是:http://gcc.gnu.org/wiki/Visibility
答案 1 :(得分:1)
答案 2 :(得分:1)
分析g++
将证明是徒劳的,因为g++
不执行链接,链接器ld
会执行链接。
分析ld
也可能不会向您显示任何有趣的内容,因为链接时间通常由磁盘I / O占主导地位,如果您的链接不是,则您不知道如何进行分析数据,除非您了解ld
内部。
如果您的链接时间明显,链接中只有15个文件,那么您的开发系统可能会出现问题[1];要么它有一个最后一段的磁盘并且一直在重试,要么你没有足够的内存来执行链接(链接通常是RAM密集型的),你的系统就像疯了一样交换。
假设您使用的是基于ELF的系统,您可能还希望尝试使用新的gold
链接器(binutils的一部分),这通常比GNU ld
快几倍。
[1]我的典型链接涉及1000个对象,产生200 + MB可执行文件,并在不到60秒内完成。