Теперь я немного изучил это в контексте моего собственного проекта и решил, что это стоит полного ответа, а не просто комментария. Этот ответ основан на наборе инструментов Apple для macOS (который использует clang, а не gcc), но я думаю, что в обоих случаях все работает одинаково.
Ключом к этому является включение «оптимизации времени компоновки» при создании библиотек и исполняемых файлов. Механика этого на самом деле очень проста — просто передайте -flto
в gcc и ld в командной строке. Это имеет два эффекта:
- Код (функции/методы) в объектных файлах или архивах, который никогда не вызывается, исключается из окончательного исполняемого файла.
- Компоновщик выполняет оптимизацию, которую может выполнить компилятор (например, встраивание функций), но со знаниями, которые выходят за границы единиц компиляции.
Это не поможет вам, если вы связываетесь с общей библиотекой, но может помочь, если эта общая библиотека соединяется с другими (статическими) библиотеками, которые содержат код, который общая библиотека никогда не вызывает.
С другой стороны, это уменьшило размер моего окончательного исполняемого файла примерно на 5%, чему я очень рад. YMMV.
С другой стороны, размер моих объектных файлов увеличился примерно вдвое, а время компоновки иногда резко возросло (примерно в 100 раз). Потом, если я перелинковался, это было намного быстрее. Однако такое поведение может быть особенностью цепочки инструментов Apple. Возможно, он прячет какие-то промежуточные сборки где-то по первой ссылке. В любом случае, если вы включите эту опцию только для выпускных сборок, это не должно быть серьезной проблемой.
Более подробная информация о полном наборе параметров командной строки gcc, управляющих оптимизацией, приведена здесь: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html. Найдите на этой странице flto
, чтобы сузить область поиска.
Чтобы заглянуть за кулисы, см.: https://gcc.gnu.org/onlinedocs/gccint/LTO-Overview.html
Изменить:
Немного больше информации о времени ссылки. Компоновщик Apple создает несколько огромных файлов в каталоге с именем LTOCache при создании ссылки. Я не видел их до сегодняшнего дня, поэтому они выглядят как промежуточные сборки, которые ускоряют связывание во второй раз. Что касается того, что моя начальная ссылка такая медленная, это может быть частично связано с тем, что в моем случае они созданы на сервере SMB. Но опять же, процессор был максимально загружен, так что, возможно, нет.
person
Paul Sanders
schedule
24.05.2018