2014-07-13 3 views
8

Когда я включаю Оптимизацию времени связи в GCC, созданные двоичные файлы становятся намного большими. Я ожидал, что GCC сможет удалить много повторяющихся функций и выполнить другие оптимизации в противном случае невозможным, так как же это приводит к тому, что сгенерированная продукция будет расти?Почему «Оптимизация времени связи» приводит к увеличению двоичных файлов?

флаги компилятора:

-Os -c -fno-builtin -ffunction-sections -fdata-sections -flto -mcpu=cortex-m0 -mthumb 

флаги компоновщика:

-nostdlib -s -Xlinker --gc-sections -flto -mcpu=cortex-m0 -mthumb -T 
+0

Как именно вы используете '-flto'? Покажите команды компиляции .... И дает нам более подробную информацию (версия компилятора). Вы попытались с недавним GCC (т. Е. 4.9.1, сентябрь 2014 года)? –

+1

Если вы используете -O3 (сделайте быстрый, но больший код), LTO предоставит компилятору больше возможностей сделать код быстрее (и больше). Если вы используете -Os (создаете небольшие двоичные файлы), LTO предоставляет вам больше возможностей для сокращения размера кода. –

+0

@MarcGlisse Спасибо, но я уже использую опцию -Os, иначе прошивка не будет входить в 64kb. – Muis

ответ

14

Вы обирать бинарного после связывания с -flto (она должна быть обеспечена как при компиляции и во время компоновки)?

Кстати, уведомление thatже оптимизация флаги (-flto -Os) должны быть переданы как во время компиляции и во время связи. Если вы забыли - как вы это сделали - любой из них на этапе связывания, LTO не будет работать! (При использовании make вы хотите CC=gcc -flto -Os не CFLAGS= -flto -Os).

Ты забыл -Os на ссылку времени, в дополнение из -flto; проездом -flto во время компоновки без каких-либо оптимизаций неправильно: фаза LTO бы «де-оптимизируют» в большинстве

Я знаю, что -flto добавляет много секций в объектных ELF-файлов и исполняемых файлов (эти разделы содержат сериализации внутренних представлений GCC, таких как Gimple ....). Я предполагаю (но не проверял), что ссылка не удаляет их.

Кроме того, основная точка LTO является инлайн accross несколько единиц компиляции и это, как ожидается, вырастет код. Поэтому, возможно, вам не следует использовать LTO в вашем конкретном случае.

Большинство избыточных функций уже удалены (компоновщиком «GC» на разделах) даже без LTO.

BTW, вы можете использовать objdump или readelf, чтобы узнать.

+0

Да, я использовал параметр «-s» компоновщика (Omit all debug information). Моя прошивка обычно подходит в 64 kb, но с '-ftlo' она почти удваивается по размеру. – Muis

+2

* LTO * - новая функция GCC. Оба варианта * gold * (новый компоновщик) и версия * gcc * будут влиять на формирование кода. Вы ** должны ** предоставить компоновщику те же самые параметры оптимизации, с которыми вы компилируете. Это изменение с * LTO *, о котором некоторые люди не знают. '-O3' не оптимизирован для размера, а производительности. Если вы действительно хотите размер, вы должны попробовать '-O' для компиляции и ссылки. –

+1

@Muis Вы должны попытаться разбить бинарные файлы, используя команду 'strip'. –

0

Важной вещью для LTO является поддержка плагинов рабочего компоновщика. Только с этим GCC может сделать агрессивное недостижимое удаление кода и другие оптимизаторы. Убедитесь, что у вас есть плагин с включенным компоновщиком (просто попробуйте, если связь LTO работает с -fuse-linker-plugin)

+0

Да, я уже решил проблему. Это была ошибка в моей среде IDE (LPXPresso), где параметр применяется только к компилятору, а не к компоновщику. – Muis

Смежные вопросы