Gcc LTO: Ограничить объем оптимизации

91
10

Создание LTO довольно большой общей библиотеки (многие экземпляры шаблонов) занимает довольно много времени ( > 10 минут). Теперь я знаю несколько вещей о библиотеке и могу указать какой-то "черный список" в виде объектных файлов, которые не нужно анализировать вместе (потому что между ними нет вызовов, которые должны быть встроены или так), или Я мог бы указать группы объектных файлов, которые должны анализироваться вместе. Возможно ли это как-то (без разделения lib)?

спросил(а) 2018-02-28T01:05:00+03:00 2 года, 8 месяцев назад
1
Решение
72

Существует небольшая функция ld, называемая -r/--relocatable, которая может использоваться для объединения нескольких объектных файлов в один, которые впоследствии могут быть связаны с конечным продуктом. Если вы можете получить LTO здесь, но не позже, вы можете иметь тип "частичного" LTO, который вы ищете.


Печально ld -r не будет работать; он просто объединяет всю информацию LTO, которая будет обрабатываться позже. Но вызов его с помощью драйвера gcc (gcc -r), похоже, работает:


a.c


int a() {
return 42;
}

b.c


int a(void);

int b() {
return a();
}

к.ц


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;, но между этими двумя группами не было межпроцедурной оптимизации.

ответил(а) 2018-03-08T00:18:00+03:00 2 года, 7 месяцев назад
82

Предположим, что вы хотите оптимизировать 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 объединяет несколько файлов исходного кода перед оптимизацией кода.


Edit


-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-06T20:46:00+03:00 2 года, 7 месяцев назад
-4

Вы можете полностью исключить объектный файл из процесса оптимизации времени ссылки, просто построив его без -flto.

ответил(а) 2018-03-05T19:40:00+03:00 2 года, 7 месяцев назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема