Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ LTO在使用GCC编译但使用LLVM LLD链接时有效吗?_C++_Gcc_Linker_Llvm_Lld - Fatal编程技术网

C++ LTO在使用GCC编译但使用LLVM LLD链接时有效吗?

C++ LTO在使用GCC编译但使用LLVM LLD链接时有效吗?,c++,gcc,linker,llvm,lld,C++,Gcc,Linker,Llvm,Lld,我最近发现了LLVM的链接器,lld,它因链接速度非常快而受到赞扬。事实上,我对它进行了测试,结果非常棒,与gold相比,我的链接时间大大缩短 然而,当谈到链路时间优化时,我的知识是有限的。据我在互联网上阅读的资料所知,目标文件中产生了一些额外的代码,表示一些内部编译器结构,然后在链接阶段使用这些结构。因此,我关心的是,链接时间优化(及其好处)是否会受到这种编译器/链接器组合的影响。我希望你能解释一下这件事 我使用了gccversion9.2.0和lldversion10.0.0 用于生成对象文

我最近发现了LLVM的链接器,
lld
,它因链接速度非常快而受到赞扬。事实上,我对它进行了测试,结果非常棒,与
gold
相比,我的链接时间大大缩短

然而,当谈到链路时间优化时,我的知识是有限的。据我在互联网上阅读的资料所知,目标文件中产生了一些额外的代码,表示一些内部编译器结构,然后在链接阶段使用这些结构。因此,我关心的是,链接时间优化(及其好处)是否会受到这种编译器/链接器组合的影响。我希望你能解释一下这件事

我使用了
gcc
version
9.2.0
lld
version
10.0.0

用于生成对象文件的命令:

/opt/gcc/9.2.0/bin/c++-fPIE-flto-ffat lto对象-fuse链接器插件-m64-O3-g-DNDEBUG-o my_object.cpp.o-c my_source_file.cpp
链接:

#-保险丝ld=gold
/opt/gcc/9.2.0/bin/c++-fPIE-flto-ffat lto对象-fuse链接器插件-m64-pie-fuse ld=gold-Wl,-z,relro-Wl,-z,now-Wl,--根据需要-静态libstdc++-静态libgcc-Wl,--线程-Wl,--线程计数,1
#-保险丝ld=lld
/opt/gcc/9.2.0/bin/c++-fPIE-flto-ffat lto对象-fuse链接器插件-m64-pie-fuse ld=lld-Wl,-z,relro-Wl,-z,now-Wl,--根据需要-static libstdc++-static libgcc-Wl,--threads-Wl,

我做了一些研究,最后得出结论,如果我们在使用
gcc
编译时使用
lld
,就不会进行LTO。我所做的:

基于这种有点模糊的表示:,我发现链接器并不是直接进行优化,而是在读取所有对象文件中的所有符号后,他将信息传递给
lto包装器
,然后该包装器通过一些其他过程进行优化。所以我用一个
hello world
cpp文件做了一个测试,用
-v
标志编译它,我确实看到了前面提到的连续调用(
collect2
(linker)->
lto包装器
->
lto1
)。但当使用默认链接器或
gold
链接器时,会出现这种情况。当我使用
-fuse ld=lld
标志时,只调用
collect2
进程。这第一件事让我相信LTO根本就没有完成

但是,嘿,可能是
lld
链接器将LTO进程内部化了,这样就不用调用任何其他进程了。所以我做了另一个测试,看看LTO是否完成(基于文章)。基本上,从一个cpp文件中,我调用了10万次在另一个cpp文件中定义的函数,一个什么都不做的函数。使用basic
-O2
优化,生成的二进制运行时间约为200毫秒,因为编译器无法优化无用的函数调用。同时使用
-flto
标志和
ld
gold
链接器时,生成的二进制文件在~2 ms内运行。但使用
lld
链接器时,生成的二进制文件也在~200 ms内运行。因此,带lto的
lld
运行速度与不带lto的
lld
运行速度一样慢。没有任何优化迹象。
这里要提到的是,如果不使用
-ffat lto objects
编译对象,则使用
lld
链接器时,link命令将失败。此标志使对象文件变大,因为编译器不仅转储lto代码,而且转储可以在没有lto的情况下链接的代码


因此,考虑到与
lld
链接的二进制文件的时间性能,以及需要使用
-ffat lto objects
编译对象这一事实,我得出结论,当使用
lld
链接器时,根本无法实现lto,但是
lld
使用编译器生成的非LTO代码来链接二进制文件。

得出了相同的结论。lld不做lto。测试gcc8和lld 10。此外,如果使用-flto选项编译,链接器总是抱怨main未定义,也必须使用-ffat lto对象。即使使用
-flto partition=none
,这是否有效?