g ++优化标志:-fuse-linker-plugin vs -fwhole-program

Hei*_*Hei 19 c++ linux g++ x86-64 ld

我正在阅读:http: //gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

它首先表明:与-flto结合使用此选项(-fwhole-program)不应该使用.相反,依赖链接器插件应该提供更安全和更精确的信息.

然后,它表明:如果程序不需要导出任何符号,则可以将-flto-fwhole-program结合使用,以允许过程间优化器使用更积极的假设,这可能会改善优化机会.当链接器插件处于活动状态时,不需要使用-fwhole-program(请参阅-fuse-linker-plugin).

这是否意味着在理论上,使用-fuse-linker-plugin-flto总是得到比使用-fwhole-program with -flto更好的可执行文件?

我尝试使用ld 分别与-fuse -linker-plugin-fwhole-program 链接,并且可执行文件的大小至少是不同的.

提前致谢.

PS我在CentOS 6上使用gcc 4.6.2和ld 2.21.53.0.1.

Nic*_*son 8

更新:请参阅下面的@PeterCordes 评论。本质上,不再需要-fuse-linker-plugin

这些差异是微妙的。首先,了解-flto实际上是做什么的。它本质上创建了一个可以稍后优化的输出(在“链接时间”)。

什么-fwhole程序确实是假定“当前编译单元代表了整个程序被编译”那是否真的是这样。因此,GCC 将假定它知道调用特定函数的所有位置。正如它所说,它可能会使用更积极的过程间优化器。我稍后会解释。

最后,-fuse-linker-plugin所做的实际上是在链接时执行优化,这通常在执行每个编译单元时完成。所以,这个被设计为与-flto配对,因为-flto意味着保存足够的信息以供以后进行优化,而-fuse-linker-plugin意味着实际进行这些优化。

那么,它们的区别在哪里呢?好吧,正如 GCC 文档所建议的那样,使用-fwhole-program原则上没有优势,因为该选项假定您必须确保正确。要打破它,只需在一个 .cpp 文件中定义一个函数并在另一个文件中使用它。您将收到链接器错误。

-fwhole-program有什么优势吗?好吧,如果您只有一个编译单元,那么您可以使用它,但老实说,它不会更好。我能够通过使用等效程序获得不同大小的可执行文件,但是在检查实际生成的机器代码时,它们是相同的。事实上,我看到的唯一区别是带有调试信息的行号不同。

  • IIRC,与 `gcc -O3 -march=native ... -flto` 链接现在可以正常工作,并执行所有必要的链接器插件功能。(将与编译时相同的优化选项传递给链接命令。) (3认同)
  • 请注意,现代 GCC“-O3”*不*启用“-funroll-loops”;仅当您使用“-fprofile-generate”/“-fprofile-use”执行 PGO 时才对热循环执行此操作。此外,GCC 8 及更高版本通常使用未对齐的加载/存储而不是完全展开的序言/尾声进行自动矢量化,以达到对齐边界。这总是很糟糕并且超级臃肿,在启动/清理上花费了大部分代码大小用于自动矢量化循环,而根本没有展开实际的重要部分!顺便说一句,clang `-O2` *确实*自动矢量化,并默认展开小循环。 (3认同)