【问题标题】:gcc LTO: Limit scope of optimizationgcc LTO:限制优化范围
【发布时间】:2018-02-27 22:05:59
【问题描述】:

一个相当大的共享库(许多模板实例化)的 LTO 构建需要相当长的时间(>10 分钟)。现在我知道一些关于库的事情,并且可以以对象文件的形式指定某种“黑名单”,不需要一起分析(因为它们之间没有调用应该内联或这样),或者我可以指定应该一起分析的目标文件组。这是否可能(不拆分库)?

【问题讨论】:

  • 您不能在开发时使用LTO 构建,而只能为候选发布版本启用它?
  • 在分析和修复性能问题时,还需要重复本地构建。
  • 我不确定你会赢多少。您是否尝试过-flto=8(或任何数字或-flto=jobserver)来获得一些并行性?
  • 我已经在使用-flto=40 :) LTO 的操作在这里描述:gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html 有三个阶段:LGEN,WPA,LTRANS。 WPA 对代码进行分区,然后 LTRANS 在分区上并行运行。我可以看到在 LTRANS 阶段运行了大约 15 个线程,但应该更多。我需要明确指导 WPA 的分区来改变它。

标签: c++ gcc lto


【解决方案1】:

ld 有一个很少使用的功能,称为-r/--relocatable,可用于将多个目标文件合并为一个,然后可以将其链接到最终产品中。如果可以让 LTO 在这里发生,但不能在以后发生,那么您就可以拥有您正在寻找的那种“部分”LTO。

很遗憾ld -r 不起作用;它只是结合了所有要在以后处理的 LTO 信息。但是通过 gcc 驱动程序 (gcc -r) 调用它似乎有效:

交流

int a() {
    return 42;
}

b.c

int a(void);

int b() {
    return a();
}

c.c

int b(void);

int c() {
    return b();
}

d.c

int c(void);

int main() {
    return c();
}
$ gcc -O3 -flto -c [a-d].c
$ gcc -O3 -r -nostdlib a.o b.o -o g1.o
$ gcc -O3 -r -nostdlib c.o d.o -o g2.o
$ gcc -O3 -fno-lto g1.o g2.o
$ objdump -d a.out
...
00000000000004f0 <main>:
 4f0:   e9 1b 01 00 00          jmpq   610 <b>
...
0000000000000610 <b>:
 610:   b8 2a 00 00 00          mov    $0x2a,%eax
 615:   c3                      retq   
...

所以main() 优化为return b();b() 优化为return 42;,但两组之间没有过程间优化。

【讨论】:

  • 感谢您发布此信息。我也更新了我的答案。
【解决方案2】:

假设您要将a.cb.c 一起优化为一个组,将c.cd.c 优化为另一组。您可以使用-combine GCC 开关,如下所示:

$ gcc -O3 -c -combine a.c b.c -o group1.o
$ gcc -O3 -c -combine c.c d.c -o group2.o

请注意,您不需要使用 LTO,因为 -combine 开关在优化代码之前会合并多个源代码文件。

编辑

-combine 目前仅支持 C 代码。实现此目的的另一种方法是使用#include 指令,如下所示:

// file group1.cpp
#include "a.cpp"
#include "b.cpp"

// file group2.cpp
#include "c.cpp"
#include "d.cpp"

那么就可以不使用LTO编译如下:

g++ -O3 group1.cpp group2.cpp

这有效地模拟了分组或部分 LTO。

然而,目前尚不清楚这种技术还是another answer 中提出的技术的编译速度更快。此外,代码可能不会以相同的方式进行优化。因此,应该比较使用每种技术生成的代码的性能。然后可以使用首选技术。

【讨论】:

  • 感谢您的建议。据我了解,combine仅适用于 C 代码,不适用于 C++。
  • @MartinRichtarsky 我刚刚检查了手册,你是对的。我错过了那一点,对不起。检查此alternative 技术。否则,我不确定ld -r 是否适用于 LTO。
  • ld -r 与 LTO 一起使用,但并不是 OP 想要的方式。它似乎只是连接 LTO 信息,最终链接无论如何都会对整个程序进行 LTO。另一方面,gcc -r -nostdlib 似乎做了 OP 想要做的事情。
  • @TavianBarnes gcc -r -nostdlib 做什么?它会生成本机目标文件吗?它适用于 LTO 吗?
  • @HadiBrais 感谢您的回答。我认为这在原则上会起作用,但我担心在编译我们的一些源文件时会导致问题。但如果 gcc -r 由于某种原因无法正常工作,这将是一个替代方案。
【解决方案3】:

您可以在不使用-flto 的情况下直接构建目标文件,从而将其从链接时间优化过程中完全排除。

【讨论】:

  • 我不想完全排除文件,我只想用“一起优化这些目标文件”之类的注释来引导优化器。
  • AFAIK,你不能那样做。您可以使用 LTO 结构(即一些 gcc 字节码)与常规机器代码一起构建目标文件,也可以不使用它们。
猜你喜欢
  • 2021-06-10
  • 1970-01-01
  • 2011-01-12
  • 1970-01-01
  • 2011-07-30
  • 1970-01-01
  • 2014-07-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多