一个相当大的共享库(许多模板实例化)的 LTO 构建需要相当长的时间(>10 分钟)。现在我知道一些关于库的事情,并且可以以不需要一起分析的目标文件的形式指定某种“黑名单” (因为它们之间没有应该被内联的调用),或者我可以指定应该一起分析的目标文件组。这可能以某种方式(不拆分库)吗?
问问题
1128 次
3 回答
4
ld
调用-r
/有一个很少使用的功能--relocatable
,可用于将多个目标文件组合成一个,稍后可以链接到最终产品中。如果可以让 LTO 在这里发生,但不能在以后发生,那么您可以拥有您正在寻找的那种“部分”LTO。
可悲的是ld -r
行不通;它只是结合了所有要在以后处理的 LTO 信息。但通过 gcc 驱动程序 ( gcc -r
) 调用它似乎有效:
交流
int a() { return 42; }
公元前
int a(void); int b() { return a(); }
抄送
int b(void); int c() { return b(); }
直流
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;
,但两组之间没有过程间优化。
于 2018-03-07T21:18:51.237 回答
3
假设您想优化a.c
和b.c
一起作为一个组和c.c
另一个d.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。
但是,尚不清楚这种技术或另一个答案中提出的技术是否更快编译。此外,代码可能不会以相同的方式进行优化。因此,应该比较使用每种技术生成的代码的性能。然后可以使用首选技术。
于 2018-03-06T17:46:09.333 回答
0
您可以通过在没有-flto
.
于 2018-03-05T16:40:09.323 回答