5

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

4

3 回答 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.cb.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 回答