Когда Вы говорите, что "оптимизация", люди склонны думать "скорость". Но что относительно встроенных систем, где скорость не все, что очень важный, но память основное ограничение? Каковы некоторые инструкции, методы и приемы, которые могут использоваться для бритья тех дополнительных килобайтов в ROM и RAM? Как каждый "представляет" код для наблюдения, где чрезмерное увеличение размера памяти?
P.S. Можно было утверждать, что "преждевременно" оптимизация для пространства во встроенных системах не все это зло, потому что Вы оставляете себя большим количеством места для хранения данных и излишнего усложнения. Это также позволяет Вам сокращать аппаратные производственные затраты, потому что Ваш код может работать на ROM/RAM меньшего размера.
P.P.S. Ссылки на статьи и книги приветствуются также!
Мой опыт от чрезвычайно ограничена встроенная среда памяти:
попробуйте что-то подобное
# vote _ links a
поймает все идентификаторы внутри ссылок голоса div id...
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery(\'#vote_links a\').click(function() {// alert(\'vote clicked\');
var det = jQuery(this).get(0).id.split("-");// alert(jQuery(this).get(0).id);
var votes_id = det[0];
$("#about-button").css({
opacity: 0.3
});
$("#contact-button").css({
opacity: 0.3
});
$("#page-wrap div.button").click(function(){
-121--1052168- Как и при всей оптимизации, сначала оптимизируйте алгоритмы, затем оптимизируйте код и данные, затем оптимизируйте компилятор.
Я не знаю, что делает ваша программа, поэтому я не могу посоветовать алгоритмы. Многие другие писали о компиляторе. Итак, вот несколько советов по коду и данным:
Если вы ищете хороший способ профилировать использование кучи приложения, проверьте инструмент valgrind massif . Он позволит делать снимки профиля использования памяти вашего приложения с течением времени, а затем вы сможете использовать эту информацию, чтобы лучше понять, где находится «низкий висящий плод», и направить свои оптимизации соответствующим образом.
Узнайте стоимость реализации некоторых функций C ++, таких как таблицы виртуальных функций и перегруженные операторы, которые создают временные объекты.
Компиляция в против с / ОС. Часто это даже быстрее, чем оптимизация для скорости в любом случае, потому что меньший размер кода == меньше пейджинга.
Скантовка COMDAT должна быть включена в компоновке (по умолчанию по умолчанию в выпуске сборки)
Будьте осторожны на упаковке структуры данных; Часто этот приводит к тому, что этот приводит к созданию компилятора (== больше памяти) для создания сборки для доступа к безветочной памяти. Использование 1 бита для логического флага является классическим примером.
Также будьте осторожны при выборе эффективного алгоритма памяти на алгоритме с лучшим временем выполнения. Это где приходят преждевременные оптимизации.
Во-первых, сообщите своему компилятору, чтобы оптимизировать для размера кода. GCC имеет флаг -OS
.
Все остальное находится на алгоритмическом уровне - используйте аналогичные инструменты, которые вы должны найти утечки памяти, но вместо этого ищите AlloCs и Frees, которые вы могли бы избежать.
Также взглянуть на обычно используемую упаковку структуры данных - если вы можете побрить байт или два от них, вы можете по существу использовать использование памяти.
Вот книга по теме Небольшое программное обеспечение для памяти: Шаблоны для систем с ограниченной памятью .
Есть много вещей, которые вы можете сделать, чтобы уменьшить свои следы памяти, я уверен, что люди написали книги на эту тему, но некоторые из основных являются:
Параметры компилятора для уменьшения размера кода (в том числе --OS и Параметры упаковки / выравнивания)
Параметры линейки для разбивки мертвого кода
, если вы загружаетесь от Flash (или ROM) в RAM, чтобы выполнить (вместо того, чтобы выполнить из Flash), затем используйте сжатый флэш-изображение и декомпресс Это с вашим загрузчиком.
Используйте статическое распределение: куча является неэффективным способом для выделения ограниченной памяти, и если она может потерпеть неудачу из-за фрагментации, если оно ограничено.
Инструменты для поиска стека High-Watermark (обычно они заполняют стек с рисунком, выполняют программу, затем посмотрите, где шаблон остается), чтобы вы могли оптимально установить размер (ы) стека
и, конечно, , оптимизация алгоритмов, которые вы используете для следа памяти (часто за счет скорости)
Наряду с тем, что все остальные сказали, что я просто хотел бы добавить, не использовать виртуальные функции, потому что с виртуальными функциями должны быть созданы VTable, которые могут занимать, кто знает, сколько места.
также следит за исключением. С GCC я не верю, что есть растущий размер для каждого блока Try-Catch (кроме 2 функции Call
S для каждого Try-Catch), но есть функция фиксированного размера, которая должна быть связана в котором можно тратить драгоценные байты
Профилирующий код или блокировка данных можно сделать через файлы карты: для GCC см. здесь , для VS см. здесь .
Я еще не видел полезный инструмент для профилирования размеров, хотя (и у вас нет времени, чтобы исправить мой взгляд против Addin).
Как и во всех оптимизации, сначала оптимизация алгоритмов, Второй оптимизируйте код и данные, наконец оптимизируйте компилятор.
Я не знаю, что делает ваша программа, поэтому я не могу совет по алгоритмам. Многие другие написали о компиляторе. Итак, вот несколько советов по коду и данным:
Наверху того, что предлагают другие:
Предельное использование функций C ++, напишите как в ANSI C с незначительными расширениями. Стандарт (STD: :) Шаблоны используют большую систему динамического распределения. Если вы можете, избегайте шаблонов в целом. В то время как не по своей природе вредно, они делают его слишком легко создавать лоты и много машинного кода из простого, чистого, элегантных инструкций высокого уровня. Это поощряет написание таким образом, что - несмотря на все преимущества «чистый код» - очень память голоден.
Если вы должны использовать шаблоны, напишите свои собственные или используемые, предназначенные для встроенного использования, пройдите фиксированные размеры как параметры шаблона, и напишите программу тестирования, чтобы вы могли проверить свой шаблон и проверять свой вывод, чтобы убедиться, что компилятор не Создание ужасного кода сборки для мгновения его.
Совместите свои структуры вручную или используйте пакет #Pragma
{char a; long b; char c; long d; char e; char f; } //is 18 bytes,
{char a; char c; char d; char f; long b; long d; } //is 12 bytes.
по той же причине, используйте централизованную глобальную структуру хранения данных вместо рассеянных локальных статических переменных.
Разумное равновесие использование Malloc () / новых и статических структур.
Если вам нужно подмножество функциональных возможностей данной библиотеки, рассмотрите возможность написания собственного.
разверните короткие петли.
for(i=0;i<3;i++){ transform_vector[i]; }
дольше, чем
transform_vector[0];
transform_vector[1];
transform_vector[2];
, не делайте этого на более длинные.
Упакуйте несколько файлов вместе, чтобы позволить компилятору вставлять короткие функции и выполнять различные оптимизации линкера не могут.
const
. Это позволит избежать скопированных данных от Flash в RAM Одним из правил философии UNIX Philosophy может помочь сделать код более компактным:
Правило представления: сгибание знаний в данных, поэтому логика программы может быть глупо и надежный.
Я не могу посчитать, сколько раз я видел сложную логику ветвления, охватывая многие страницы, которые могли бы сложить в приятную компактную таблицу правил, констант и указателей функции. Штатные машины часто можно представить таким образом (штат-шаблон). Узор команд также применяется. Это все о декларативных против императивных стилей программирования.
вместо регистрации простого текста, кодов событий журнала и двоичных данных. Затем используйте «скатербюр», чтобы восстановить сообщения о событиях. Сообщения в развеселении могут даже содержать спецификаторы формата в стиле PrintF, чтобы значения данных событий аккуратно отображаются в тексте.
Каждый поток нуждается в его блоке памяти для стека и TSS. Там, где вам не нужно вытеснение, рассмотрите возможность выполнить ваши задачи выполнять совместно в рамках одного и того же потока ( совместное многозадачность ).
, чтобы избежать фрагментации кучи, я часто видел отдельных модулей крупных статических буферов памяти для их собственного использования, даже когда память только изредка требуется только. Вместо этого пул памяти может быть использован вместо этого, поэтому память используется только «по запросу». Тем не менее, этот подход может потребовать тщательного анализа и приборов, чтобы убедиться, что пулы не истощаются во время выполнения.
в встроенных системах, когда только одно приложение работает бесконечно, вы можете использовать динамическое распределение в разумном способе, который не приводит к фрагментации: просто динамически выделяет один раз в различных процедурах инициализации, а не Бесплатно память. Резерв ()
Ваши контейнеры на правильную емкость и не позволяйте им автоматически расти. Если вам нужно часто выделять / бесплатные буферы данных (скажем, для пакетов связи), затем используйте пулы памяти. Однажды я даже расширил рутины C / C ++, чтобы он преподавал мою программу, если что-то пытается динамически распределять память после последовательности инициализации.
Создайте файл карты с вашего линкера. Он покажет, как распределяется память. Это хорошее начало при оптимизации для использования памяти. Он также покажет все функции и о том, как выложено кодовое пространство.
Похоже, что мой .inf. Вот что сработало для меня:
[version]
Signature="$CHICAGO$"
AdvancedINF=2.0
[Setup Hooks]
hook1=hook1
[hook1]
run=msiexec.exe /i "%EXTRACT_DIR%\MySetup.msi" /qn
Чтобы сделать cab:
CABARC.EXE N MyActiveX.cab MySetup.msi setup.inf
-121--4460497- Диаграммы последовательности подходят для представления вызовов функций, и вы можете также указать параметры и возвращенные значения.
-121--1683697-Многие уже были упомянуты, но вот мой список:
Последнее, но не менее важное - при поиске наименьшего возможного размера кода - не переусердствуйте . Следите также за производительностью и ремонтопригодностью. Избыточно оптимизированный код имеет тенденцию к очень быстрому распаду.
Не бойтесь писать «маленькие языки» в вашей программе. Иногда таблица строк и переводчик может сделать многое. Например, в системе я работал, у нас много внутренних таблиц, которые должны быть доступны различными способами (петля, что угодно). У нас есть внутренняя система команд для ссылки на таблицы, которые образуют свой вид половинного пути, который довольно компактный для того, что он получает дон.
Но будьте осторожны! Знайте, что вы пишете такие вещи (я писал случайно, я сам), и документирую то, что вы делаете. Оригинальные разработчики, похоже, не осознают то, что они делали, поэтому намного сложнее управлять, чем должно быть.