В IAR Embedded Workbench IDE есть возможность выборочно управлять оптимизацией отдельных модулей, что позволяет значительно повысить эффективность всего кода в целом, и упрощает отладку.
[IAR EWB for ARM 5.50: настройка оптимизации модулей проекта]
Для удобной отладки по исходному коду оптимизацию обычно отключают. Это позволяет качественно просматривать значение локальных переменных программы, точно выполнять пошаговое выполнение программы по исходному коду. Для отладки создается конфигурация Debug, где оптимизация выключена, а для готовой рабочей программы делается конфигурация Release, где оптимизация включена. Не секрет, что большой проект обычно содержит довольно много ошибок и неточностей, которые не позволяют сразу включить оптимизацию для всего проекта целиком (т. е. нельзя сразу применить конфигурацию Debug). Например, в конфигурации Debug программа работает, а в конфигурации Release, где включена оптимизация - появляются глюки и программа становится нерабочей.
Обычно проект состоит из большого количества модулей, которые находятся в разной степени готовности. Например, некоторые подпрограммы использовались довольно давно и хорошо отлажены (например, подпрограммы графики, низкоуровневый вывод на экран ЖКИ), а другие - только пишутся, и должны активно отлаживаться. Подпрограммы, которые давно отлажены, отлаживать пока нет необходимости, и для них можно отдельно включить оптимизацию, что значительно ускорит работу программы, либо позволит сэкономить на памяти (в зависимости от того, какая оптимизация используется). Оптимизация для отдельного модуля может быть настроена через контекстное меню модуля Options..., поставить галочку Override inherited settings, раздел C/C++ Compiler -> Optimizations -> Level, можно выбирать Balanced, Size, Speed.
Кроме того, на закладке Code можно выбрать тип генерируемого кода Arm или Thumb, что влияет на размер кода и его быстродействие.
После настройки индивидуальных опций для модуля в окошке дерева модулей проекта (View -> Workspace) напротив него появляется черная галочка.
Можно назначить отдельные настройки для целого раздела проекта - группы модулей, если они размещены в отдельной папке браузера проекта. Здесь имеется в виду не папка файловой системы, а папка проекта, которая отражает его логическую структуру (например, модули работы с графикой могут лежать в отдельной папке GUIfunctions дерева проекта IAR).
[IAR Embedded Workbench ver. 4.41]
Имеется 3 основных инструмента управления оптимизацией:
1. Оптимизация на уровне проекта. 2. Оптимизация на уровне модуля (файла) кода. 3. Оптимизация на уровне функции (#pragma optimize).
Оптимизация на уровне проекта задается также, как в IAR 5.50, для всего проекта целиком, в свойствах проекта.
Оптимизация на уровне модуля задается также, как как в IAR 5.50, для отдельного файла модуля кода, если у него отключить наследование свойств от всего проекта.
Оптимизация с помощью директивы #pragma optimize позволяет управлять оптимизацией для каждой функции модуля по отдельности.
#pragma optimize=тип_оптимизации уровень_оптимизации
Здесь тип_оптимизации может быть s (оптимизация по скорости) или z (оптимизация по объему кода), а уровень_оптимизации может быть 2 (none, отсутствие оптимизации), 3 (low, низкая оптимизация), 6 (medium, средняя оптимизация), 9 (high, максимальная оптимизация). Пример применения для функции:
//Отключение оптимизации для функции Wait, чтобы работала
// задержка через цикл for.
#pragma optimize=z 2
void Wait (u32 cycles)
{
for (;cycles;cycles--);
}
//Конец функции, в этом месте отключение оптимизации уже не
// действует.
Применение #pragma optimize имеет особенности:
• Только для снижения уровня оптимизации. Отсюда вывод - если хотите применять #pragma optimize с максимальными возможностями, то на уровне модуля или проекта нужно включить максимальный уровень (High) для оптимизации. • Нельзя в пределах одного модуля применять разные типы оптимизации. Отсюда вывод - нужно помнить, какой тип оптимизации задан на уровне модуля, и соответственно этому типу правильно задавать параметр s или z для директивы #pragma optimize. • Может применяться только к функции или процедуре, в теле функции её использовать нельзя. • Директива должна стоять сразу перед функцией. • По окончании тела функции действие директивы завершается. Отсюда вывод - лишний повод делить код на функции, чтобы можно было удобно использовать директиву #pragma optimize.
Более подробно про оптимизацию IAR 4.41 можно почитать в даташите EWARM_CompilerReference.pdf (меню IAR Help -> ARM C/C++ Compiler Reference Guide), разделы Part 1. Using the compiler -> Efficient coding for embedded applications -> CONTROLLING COMPILER OPTIMIZATIONS и Part 2. Compiler reference -> Descriptions of pragma directives -> optimize.
[Директива #pragma optimize в IAR 5.50]
Директива #pragma optimize для IAR 5.50 работает точно так же, как описано в предыдущем разделе для версии IAR 4.41. Она точно так же предназначена только для понижения уровня оптимизации, и действует только на ту функцию или процедуру, перед которой помещена. Отличия только в количестве уровней оптимизации и используемых опций для этого, поскольку в версии 5.50 возможности настройки оптимизации расширились. Общий синтаксис #pragma optimize:
#pragma optimize=param[ param...]
Здесь param один параметр (или несколько параметров), которые будут определять оптимизацию для функции, перед которой указана директивы.
Опция оптимизации param |
Описание |
balanced|size|speed |
Оптимизация с балансом по скорости и размеру, оптимизация по размеру или оптимизация по скорости. |
none|low|medium|high |
Указывает уровень оптимизации. |
no_code_motion |
Отключает code motion. |
no_cse |
Отключает common subexpression elimination. |
no_inline |
Отключает inlining функции. |
no_tbaa |
Отключает type-based alias analysis. |
no_unroll |
Отключает развертку циклов (loop unrolling). |
no_scheduling |
Отключает instruction scheduling. |
Параметры speed, size и balanced дают эффект только когда на уровне модуля (или проекта) задана high оптимизация, и может использоваться только один выбранный вариант, поскольку невозможно оптимизировать одновременно и для скорости, и для размера. Также нельзя использовать макросы препроцессора, встроенные в эту директиву pragma. Любой такой макрос не будет расширен препроцессором.
Примечание: если Вы используете директиву #pragma optimize, чтобы указать уровень оптимизации выше, чем это указано в опциях компилятора (или в настройках проекта или модуля), то директива pragma будет игнорирована.
Примеры:
#pragma optimize=speed
int small_and_used_often()
{
...
}
#pragma optimize=size no_inline
int big_and_seldom_used()
{
...
}
|