Измерение использования статической памяти для C++, портированной на встроенную платформу

Я создал небольшую программу в качестве подтверждения концепции для системы, которая должна быть реализована на встроенной платформе. Программа написана на C++11 с использованием std и скомпилирована для запуска на ноутбуке. Последняя программа, которая должна быть реализована позже, является встроенной системой. У нас нет доступа к компилятору встроенной платформы.

Я хотел бы знать, есть ли способ определить статическую память программ (размер скомпилированных двоичных файлов) разумным и сопоставимым способом, когда она должна быть перенесена на встроенную платформу. Требование состоит в том, что размер двоичного файла составляет менее 10 КБ. Наш двоичный файл имеет размер 700 Кбайт при компиляции и удалении со следующими флагами:

g++ options:     -Os -s -ffunction-sections -fdata-sections
linker options:  -s -Wl,--gc-sections

strip libmodel.a -s -R .comment -R .gnu.version --strip-unneeded -R .note

Это заняло 4 МБ, прежде чем мы использовали параметры полосы и оптимизации.

Я все еще далеко, и это не такая уж большая программа. Как я могу оправдать сравнение каким-либо образом с эквивалентной программой на встроенной платформе.

2 ответа

Решение

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

objdump ( http://www.gnu.org/software/binutils/) или, возможно, elfdump или цепочка инструментов elf ( http://sourceforge.net/apps/trac/elftoolchain/) поможет вам определить размер различных сегментов, данных и текста, а также размер отдельных функций и глобальных переменных и т. д. Все это программы "заглядывают" в ваш скомпилированный двоичный файл и извлекают много информации, такой как размер раздела.text,.data, перечисляют различные символы, их расположение и размеры, и даже могут разбивать раздел.text...

Пример использования elfdump в образе ELF test.elf может быть elfdump -z test.elf > output.txt, Это сбросит все, включая разбор текстового раздела. Например, из elfdump в моей системе я видел

Section #6: .text, type=NOBITS, addr=0x500, off=0x5f168
             size=149404(0x2479c), link=0, info=0, align=16, entsize=1
             flags=<WRITE,ALLOC,EXECINSTR>
Section #7: .text, type=NOBITS, addr=0x24c9c, off=0x5f168
             size=362822(0x58946), link=0, info=0, align=4, entsize=1
             flags=<WRITE,ALLOC,EXECINSTR,INCLUDE>
....
Section #9: .rodata, type=NOBITS, addr=0x7d5e4, off=0x5f168
             size=7670(0x1df6), link=0, info=0, align=4, entsize=1
         flags=<WRITE,ALLOC>

Так что я могу видеть, сколько занимает мой код (разделы.text) и мои данные только для чтения. Позже в файле я тогда вижу...

Symbol table ".symtab"
         Value    Size     Bind Type Section                  Name
         -----    ----     ---- ---- -------                  ----
218      0x7c090  130      LOC  FUNC .text               IRemovedThisName

Итак, я вижу, что моя функция IRemovedThisName занимает 130 байтов. Быстрый скрипт позволит вам перечислить функции, отсортированные по размеру, и переменные, отсортированные по размеру. Это может указать вам места для оптимизации...

Для хорошего примера objdump попробуйте http://www.thegeekstuff.com/2012/09/objdump-examples/, в частности, раздел 3, в котором показано, как получить содержимое заголовков разделов с помощью -h вариант.

Что касается того, как программа будет сравниваться на двух разных платформах, я думаю, вам просто нужно будет скомпилировать на обеих платформах и сравнить результаты, которые вы получаете от вашей obj/elfdump в каждой системе - результаты будут зависеть от набора системных инструкций, от того, насколько хорошо может оптимизироваться каждый компилятор, от общих аппаратных архитектурных различий и т. д.

Если у вас нет доступа к встроенной системе, вы можете попробовать использовать на своем ноутбуке кросс-компилятор, настроенный для вашей конечной цели. Это даст вам двоичный файл, подходящий для встроенной платформы, и инструменты для анализа файла (то есть кросс-платформенная версия objdump). Это дало бы вам некоторые цифры о том, как программа будет выглядеть на возможном встроенном sys.

Надеюсь это поможет.

РЕДАКТИРОВАТЬ: Это также поможет Как получить размер функции C изнутри программы на C или встроенной сборки?

Оказалось, что включенные библиотеки занимали огромное пространство (как было указано в комментарии) и, удалив их, можно было уменьшить размер почти до нуля в сочетании со следующими флагами:

set(CMAKE_CXX_FLAGS "-Os -s  -ffunction-sections -fdata-sections -DNO_STD -fno-rtti -fno-exceptions")
set(CMAKE_EXE_LINKER_FLAGS "-s -Wl,--gc-sections")  

И удаляя ненужный код, используя:

strip libmodel.a -s -R .comment -R .gnu.version --strip-unneeded -R .note

4 МБ можно уменьшить до 9,4 КБ, что ниже нашего лимита.

В итоге, std занимает огромное количество места.

Другие вопросы по тегам