Как настроить IAR для получения эффективного кода Печать
Добавил(а) microsin   

Перевод документации [1], посвященный обзору настроек проекта IAR для получения быстрого и/или компактного кода.

[Размер или скорость?]

Уровни оптимизации и их тип [2] могут быть указаны как для всего приложения (проекта) в целом, так и для каждого файла (модуля) исходного кода индивидуально. Внутри исходного кода директива #pragma optimize позволяет также управлять оптимизацией (в сторону понижения) для каждой отдельной функции.

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

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

IAR-optimization-options

На этом скриншоте показан диалог настройки оптимизации, который доступен как для проекта целиком, так и для отдельного модуля (если отменить наследование свойств модуля установкой галочки Override inherited settings). Таким образом, чтобы эффективно провести оптимизацию, нужно сделать выбор между скоростью и быстродействием, после чего настроить соответствующие опции оптимизации.

[Модель памяти]

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

• Уменьшится диапазон адресов, увеличится количество относительных переходов (они обычно работают быстрее).
• Для некоторых микроконтроллеров уменьшится размер инструкций.
• Уменьшится размер указателей.
• Код будет работать быстрее.
• Размер кода уменьшится.

[Адаптация рабочего окружения (runtime environment)]

• По умолчанию runtime-библиотеки компилируются с самым высоким уровнем оптимизации. Вы должны перекомпилировать их, если оптимизируете код для скорости.

• Выберите необходимый уровень поддержки функциональности библиотеки для определенного стандарта наподобие поддержки локализации (locale), дескрипторов файла (file descriptors), многобайтной кодировки (multibytes). Это делается путем выбора конфигурации библиотеки.

IAR-Library-Configuration-options

• Выберите опции библиотеки для функций форматирования ввода scanf и вывода printf в соответствии с Вашими потребностями. По умолчанию не выбран самый маленький форматтер.

IAR-Library-formatter-options

[Типы данных значительно влияют на размер кода и скорость]

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

IAR-plain-char-options

[Для наилучшего быстродействия проверьте опции, специфичные для платформы]

Примеры:

• Эффективные режимы адресации сделают доступ к памяти более оптимальным.
• Использование регистров для констант / переменных позволит получить максимальную скорость по сравнению с хранением данных констант / переменных в памяти.
• Четное выравнивание функций дает дополнительную скорость.
• Байтовое выравнивание объектов позволяет уменьшить расход памяти для них, но приводит к увеличению объема кода и снижению быстродействия.

[Используйте подходящий код для анализа быстродействия]

• Бенчмарки для встраиваемой системы должны быть привязаны к функциям встраиваемых программ.

• Реальные приложения обычно хорошо подходят для бенчмарков, однако убедитесь, что код сможет запуститься. Линкер обычно удаляет неиспользуемый код и переменные, но не все линкеры имеют такую возможность.

• Убедитесь, что на код теста не повлияли функции поддержки теста. Например, это справедливо для использования функции printf().

unsigned long fib (unsigned long x)
{
   if (x > 2)
   {
      printf("%ld\n", x);  //это обезобразит тест
      return (fib(x-1) + fib(x-2));
   }
   else
      return (1);
}

• Сравните результаты линкованного кода по размеру. Один компилятор может использовать inline-код, а другой делать вызовы библиотечных функций.

• Хорошо изучите приложение, которое Вы используете для бенчмарка!

[Ссылки]

1. How to tune IAR Embedded Workbench for best performance site:iar.com.
2. Управление оптимизацией в IAR.