Сколько стоит 32 КБ скомпилированного кода - PullRequest
8 голосов
/ 23 августа 2010

Я планирую использовать программируемую плату Arduino .У них достаточно ограниченный объем флэш-памяти в диапазоне от 16 до 128 кБ для хранения скомпилированного кода C или C ++.

Есть ли способы оценить сколько (стандартного) кода он будет представлять?

Полагаю, это очень расплывчато, но я ищу только порядок величин.

Ответы [ 6 ]

6 голосов
/ 23 августа 2010

Вывод команды size является хорошей отправной точкой, но не дает вам всей необходимой информации.

$ avr-size program.elf
text            data    bss     dec     hex filename

Размер вашего изображения обычно немного больше, чемсумма текста и данных разделов.Секция bss по сути сжатая, потому что это все 0.Могут быть и другие релевантные разделы, которые не перечислены по размеру.

Если ваша система сборки настроена так, как я использовал ранее для микроконтроллеров AVR, то вы получите * .elfфайл, а также файл * .bin и, возможно, файл * .hex.Файл * .bin - это фактическое изображение, которое будет храниться во флэш-памяти процессора процессора, поэтому вы можете проверить его размер, чтобы определить, как растет ваша программа, когда вы вносите в нее изменения.Файл * .bin извлекается из файла * .elf с помощью команды objdump и некоторых флагов, которые я сейчас не могу вспомнить.

Если вы хотите знать, как угадать, сколько выКод на C или C ++ будет генерироваться при компиляции, это намного сложнее.Я наблюдал 10-кратное увеличение в функции, когда я пытался использовать uint64_t, а не uint32_t, когда все, что я делал, увеличивало его (это было примерно в 5 раз больше кода, чем я думал).В основном это было связано с тем, что оптимизации gcc avr не были лучшими, но небольшие изменения в размере кода могли бы появиться из, казалось бы, невинного кода.

Это, вероятно, будет усилено с использованием C ++, который имеет тенденцию скрывать большевещи, которые превращаются в код, чем С.Главным среди вещей, которые скрывает C ++, являются вызовы деструкторов и множество разыменований указателей, которые связаны с указателем this в объектах, а также с секретным указателем, который многие объекты имеют для своей таблицы виртуальных функций и статических переменных класса.

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

Некоторые советы для небольших программ в AVR:

  • Используйте uint8_t и int8_t вместо int, когда можете.Вы также можете использовать uint_fast8_t и int_fast8_t, если хотите, чтобы ваш код был переносимым.Это может привести к тому, что многие операции будут занимать только половину кода, потому что int - это два байта.

  • Осознайте такие вещи, как строковые и структурные константы и литералы и как / гдеони сохраняются.

  • Если вы не боитесь этого, прочитайте руководство по сборке AVR.Вы можете получить представление о типах инструкций, а также о типе кода C, который легко сопоставляется с этими инструкциями.Используйте такой код С.

3 голосов
/ 23 августа 2010

Вы не можете там сказать.Длина не скомпилированного кода имеет мало общего с длиной скомпилированного кода.Например:

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main()
{
  std::vector<std::string> strings;
  strings.push_back("Hello");
  strings.push_back("World");
  std::sort(strings.begin(), strings.end());
  std::copy(strings.begin(), strings.end(), std::ostream_iterator<std::string>(std::cout, ""));
}

vs

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

int main()
{
  std::vector<std::string> strings;
  strings.push_back("Hello");
  strings.push_back("World");
  for ( int idx = 0; idx < strings.size(); idx++ )
    std::cout << strings[idx];
}

Оба имеют одинаковое количество строк и выдают одинаковый вывод, но первый пример включает создание экземпляра std :: sort,что, вероятно, на порядок больше кода, чем остальной код здесь.

Если вам абсолютно необходимо подсчитать количество байтов, используемых в программе, используйте ассемблер.

2 голосов
/ 27 сентября 2010

Попробуйте создать упрощенную версию своего приложения, сосредоточившись сначала на наиболее ценной функции, а затем начните добавлять «хорошие (и классные) вещи, которые нужно иметь».Следите за использованием байтов, показанным в Arduino IDE, когда вы проверяете свой код.

В качестве приблизительного указания, мое первое приложение (светодиодный индикатор, управляемый с помощью кнопки), требует 1092 байта.Это примерно 1 КБ из 32 КБ.Довольно маленький след для кода C ++!

Больше всего меня беспокоит ограниченный объем оперативной памяти (1 Кб).Если процессорный стек занимает часть его, то для создания каких-либо структур данных не так уж и много.

У меня был Arduino только на 48 часов, так что есть еще много, чтобы эффективно его использовать ;-) Но это очень весело использовать:).

2 голосов
/ 23 августа 2010

Загрузите IDE arduino и «проверьте» часть своего существующего кода или посмотрите примеры эскизов.Он скажет вам, сколько байтов этот код, что даст вам представление о том, сколько еще вы можете вписаться в данное устройство.Выбрав несколько примеров случайным образом, пример веб-сервер составляет 5816 байт, а LCD hello world - 2616. Оба используют внешние библиотеки.

1 голос
/ 23 августа 2010

Это довольно немного для достаточно сложного программного обеспечения, но вы начнете сталкиваться с ограничением, если вы хотите, чтобы у него было много различных функциональных возможностей. Кроме того, если вы хотите хранить довольно много статических строк и данных, это может достаточно быстро с этим справиться. Но 32 КБ - это приличная сумма для встроенных приложений. Это, как правило, ОЗУ, с которым у вас проблемы в первую очередь!

Кроме того, довольно часто компиляторы C ++ для встроенных систем намного хуже, чем компиляторы C. То есть они нигде не так хороши, как компиляторы C ++ для обычных настольных ОС (с точки зрения создания эффективного машинного кода для целевой платформы).

0 голосов
/ 23 августа 2010

В системе linux вы можете провести несколько экспериментов со статически скомпилированными примерами программ. Э.Г.

$ size `which busybox `
text            data    bss     dec     hex filename
1830468    4448   25650 1860566  1c63d6 /bin/busybox

Размеры даны в байтах. Этот вывод не зависит от формата исполняемого файла, поскольку размеры различных разделов внутри формата файла. Текстовый раздел содержит машинный код и const stufff. Раздел данных содержит данные для статической инициализации переменных. Размер bss - это размер неинициализированных данных - конечно, неинициализированные данные не нужно хранить в исполняемом файле.)

Ну, busybox содержит множество функций (как и все обычные команды оболочки, оболочка и т. Д.).

Если вы связываете собственные примеры с gcc -static , имейте в виду, что используемый вами libc может значительно увеличить размер программы и что использование встроенного libc может быть намного более эффективным с точки зрения места.

Чтобы проверить, что вы можете проверить diet-libc или uclibc и ссылку на него. На самом деле, busybox обычно связан с uclibc.

Обратите внимание, что размеры, которые вы получаете таким образом, дают вам порядка . Например, ваша рабочая станция, вероятно, использует другую архитектуру ЦП, отличную от платы Arduino, и машинный код другой архитектуры может более или менее различаться по размеру (из-за размеров операнда, доступных инструкций, кодировки кода операции и т. Д.).

Для продолжения приблизительного порядка рассуждений busybox содержит примерно 309 инструментов (включая демон ftp и тому подобное), то есть средний размер кода инструмента busybox примерно равен 5k.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...