Советы по сокращению времени компоновки C++

У меня есть проект, который связывается с g++ и ld примерно за 8 секунд.

Он использует кучу статических библиотек, большая часть кода написана на C++.

Меня интересует общий список советов о том, как сократить время ссылки. Что-нибудь от «не включайте отладочные символы» до «сделайте свой код менее спагетти»


person Lucas Meijer    schedule 29.12.2010    source источник
comment
Используете ли вы генерацию кода времени ссылки? Это будет производить более быстрый код, но время компоновки увеличится.   -  person Billy ONeal    schedule 29.12.2010
comment
8 секунд быстро. Это не похоже на то, о чем стоит беспокоиться. Насколько велик проект?   -  person CB Bailey    schedule 29.12.2010
comment
Платформа и компилятор? С GCC и binutils gold работает быстрее, чем (классический) ld , и clang может (а может и не быть) быстрее.   -  person ephemient    schedule 29.12.2010
comment
Я могу выполнить полную сборку и связать свой проект примерно с 800 000 LOC примерно за 10 секунд.   -  person David Heffernan    schedule 29.12.2010
comment
0,8 миллиона строк кода за 10 секунд? У меня есть отдельные единицы перевода, которые занимают больше времени!   -  person Billy ONeal    schedule 29.12.2010


Ответы (6)


Я имел дело с этим в течение многих лет на предыдущей работе. Компоновщик GNU просто имеет серьезные проблемы с производительностью при компоновке большого количества статических библиотек. В какой-то момент время компоновки соответствовало времени компиляции, что показалось нам настолько странным, что мы действительно исследовали это и выяснили.

Вы можете попытаться объединить свои статические библиотеки в «суперобъект» перед связыванием. Вместо такой ссылки:

$ g++ -o program program.o $STATIC_LIBS

Вы можете попробовать это:

$ ld -r -o libraries.o --whole-archive $STATIC_LIBS
$ g++ -o program program.o libraries.o

Обратите внимание, что этот метод дает компоновщику меньше возможностей исключить неиспользуемый объектный код, поэтому ваши двоичные файлы могут несколько увеличиться в размере.

person brewbuck    schedule 29.12.2010
comment
Если вы используете этот метод для кода C++, вам может понадобиться переключатель -Ur вместо -r (см. документацию для ld) - person anatolyg; 30.12.2010
comment
Есть ли решение osx для -Ur для кода С++? похоже ld на osx10.6 не распознает -Ur - person Lucas Meijer; 30.12.2010
comment
Увидев это, я задаюсь вопросом, улучшит ли производительность сначала связывание зависимостей. - person Alexander Oh; 23.04.2014

создайте виртуальный диск, скомпилируйте его и свяжите с жестким диском.

поскольку вы используете много статических библиотек, вы можете создать гигантскую библиотеку, содержащую все эти библиотеки, чтобы в итоге у вас была одна библиотека. удалите все библиотеки из вашего списка библиотек и добавьте гигантскую. Это уменьшает количество открытий файла до 1 для библиотек и может ускорить действия по чтению.

person engf-010    schedule 29.12.2010
comment
Разве ramdisk не та штука, которую мы использовали в 1980-х? - person anatolyg; 30.12.2010
comment
@anatolyg: Да, но он все равно лучше жестких дисков. - person engf-010; 30.12.2010

Отключите оптимизацию всей программы (хотя бы на время разработки). Используйте p-impl для уменьшения зависимостей.

person Ben Voigt    schedule 29.12.2010
comment
Разве p-impl не должен сокращать время компиляции? - person Simone; 29.12.2010
comment
@Simone: p-impl означает, что изменения в реализации одного класса требуют перекомпиляции только этой единственной единицы компиляции, а не всех потребителей. Меньшее количество измененных единиц компиляции делает инкрементное связывание более эффективным. - person Ben Voigt; 29.12.2010

8 секунд — это довольно быстро, если только вы не уверены, что это не займет так много времени. У меня есть проекты, полная перелинковка которых занимает 5-8 минут, поскольку мы не делаем добавочную компоновку в наших релизных сборках. Пробовали ли вы использовать инкрементное связывание (если вы не используете -shared, вы можете использовать -i или -r)?

person Wyatt Anderson    schedule 29.12.2010
comment
Через 5-8 минут все равно выглядит как газель. - person Martin York; 30.12.2010
comment
@Martin: Нет, я работаю над 1,2-миллионной кодовой базой LOC C++, которая использует Boost, GMP и некоторые другие неприятные библиотеки, используя хороший дизайн, diskc (8 серверов), быстрые диски и т. д., полную сборку всей кодовой базы (включая тесты) занимает около 2-2,5 минут с использованием gcc 4.4. Таким образом, для того, чтобы что-то заняло 8 минут, это должна быть очень плохо написанная или огромная кодовая база. - person ; 30.12.2010

Как насчет компиляции отладочных сборок в виде общих библиотек? Это устранит раздувание символа отладки, поскольку библиотеки импорта крошечные с информацией об отладке или без нее. Возможно, это не лучшее решение, но я думаю, что это существенно сократит время компоновки...

person rubenvb    schedule 29.12.2010
comment
Он конкретно сказал, что общих библиотек нет. И я с ним согласен — в современных системах общие библиотеки добавляют много потенциальных проблем и дают мало преимуществ. - person Tom Swirly; 21.12.2011
comment
@TomSwirly Нигде я не вижу, чтобы он упоминал о том, что он против общих библиотек. - person rubenvb; 21.12.2011

Вы можете попробовать использовать clang и lld. От godot документы

Вы также можете использовать Clang и LLD для создания Godot. У этого есть два преимущества по сравнению с настройкой GCC + GNU ld по умолчанию:

LLD связывает Godot значительно быстрее по сравнению с GNU ld или gold. Это приводит к более быстрому времени итерации.

person Community    schedule 07.05.2020