我最近发现了LLVM的链接器,lld
该链接器因快速链接而受到赞誉。确实,我测试了它,结果非常棒,与相比,我的情况下的链接时间大大缩短了gold
。
但是,当谈到链接时间优化时,我的知识是有限的。据我阅读互联网上的资料了解,目标文件中产生了一些额外的代码,这些代码代表了一些内部编译器结构,然后在链接阶段使用它们。因此,我担心的是链接时间优化(及其好处)是否受此编译器/链接器组合的影响。我希望对此事作一些解释!
我使用gcc
version9.2.0
和lld
version 10.0.0
。
我用于生成目标文件的命令:
/opt/gcc/9.2.0/bin/c++ -fPIE -flto -ffat-lto-objects -fuse-linker-plugin -m64 -O3 -g -DNDEBUG -o my_object.cpp.o -c my_source_file.cpp
对于链接:
#-fuse-ld=gold
/opt/gcc/9.2.0/bin/c++ -fPIE -flto -ffat-lto-objects -fuse-linker-plugin -m64 -pie -fuse-ld=gold -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -static-libstdc++ -static-libgcc -Wl,--threads -Wl,--thread-count,1
#-fuse-ld=lld
/opt/gcc/9.2.0/bin/c++ -fPIE -flto -ffat-lto-objects -fuse-linker-plugin -m64 -pie -fuse-ld=lld -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -static-libstdc++ -static-libgcc -Wl,--threads -Wl,
我做了一些研究,最后得出结论为我自己,如果我们不使用LTO完成lld
与编译时gcc
。我做了什么:
基于这个模糊的演示:https : //www.slideshare.net/chimerawang/gcc-lto,我发现链接器不是直接进行优化,而是从所有目标文件中读取了所有符号后,他将信息传递给lto-wrapper
谁,然后通过其他一些过程进行优化。因此,我使用hello-world
cpp文件进行了测试,并使用该-v
标志对其进行了编译,实际上,我看到了前面提到的(collect2
(linker)-> lto-wrapper
-> lto1
)的连续调用。但这是使用默认链接程序或gold
链接程序时的。当我使用该-fuse-ld=lld
标志时,仅collect2
调用该过程。这第一件事使我相信LTO根本没有完成。
但是,也许,lld
链接器将LTO进程内部化了,所以无需调用任何其他进程即可完成该过程。所以我做了另外一个测试,看看是否LTO完成(基于此文章)。基本上,我从一个cpp文件中调用1亿次来调用另一个cpp文件中定义的函数,而该函数什么也不做。使用基本-O2
优化,由于编译器无法优化无用的函数调用,因此生成的二进制文件将在〜200ms内运行。当同时使用-flto
标志和ld
或gold
链接器时,生成的二进制文件将在〜2 ms内运行。但是当使用lld
链接器时,生成的二进制文件也将在〜200ms内运行。因此,lld
使用lto时的运行速度与lld
不使用lto时一样慢。没有任何优化的迹象。
这里要提到的是,使用lld
链接器时,如果不使用编译对象,则link命令将失败-ffat-lto-objects
。该标志使目标文件更大,因为编译器不仅转储lto代码,而且转储无需lto即可链接的代码。
因此,考虑到与链接的二进制文件的时间性能lld
以及需要使用编译对象的事实-ffat-lto-objects
,我得出结论,使用lld
链接器时,根本不会实现LTO,而是lld
使用了编译器生成的非LTO代码为了链接二进制文件。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句