Управляйте генерацией служебных функций с фиксированной точкой

Оптимизируйте сгенерированный код, используя указанные минимальное и максимальное значения

Программное обеспечение Fixed-Point Designer™ использует представимые минимальные и максимальные значения и постоянные значения, чтобы определить, возможно ли оптимизировать сгенерированный код, например, путем исключения ненужных служебных функций и кода насыщения из сгенерированного кода.

Эта оптимизация приводит к:

  • Сокращение потребления ПЗУ и ОЗУ

  • Улучшенная скорость выполнения

Когда вы выбираете параметр конфигурации Optimize using specified minimum and maximum values, программное обеспечение принимает во внимание информацию о входе области значений, также известную как design minimum and maximum, которую вы задаете для сигналов и параметров в вашей модели. Он использует эти минимальные и максимальные значения, чтобы вывести информацию о области значений для нисходящих сигналов в модели, а затем использует эту выведенную информацию о области значений для упрощения математических операций в сгенерированном коде, когда это возможно.

Необходимые условия

Параметр Optimize using specified minimum and maximum values появляется только для целей на основе ERT и требует Embedded Coder® лицензия при генерации кода.

Как сконфигурировать модель

Чтобы сделать оптимизацию более вероятной:

  • Предоставьте как можно больше проектной минимальной и максимальной информации. Задайте минимальное и максимальное значения для сигналов и параметров в модели для:

    • Inport и Outport блоки

    • Блочные выходы

    • Блочные входы, например, для блоков MATLAB Function и Stateflow Chart

    • Simulink.Signal объекты

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

     Как включить проверку области значений симуляции

  • Используйте типы данных с фиксированной точкой с двоичным масштабированием только для точек (степень двойки).

  • Предоставьте расчетные минимальную и максимальную информацию в восходящем направлении блоков как можно ближе к входам блоков. Если вы задаете минимальное и максимальное значения для выхода блока, эти значения, скорее всего, повлияют на выходы блоков непосредственно ниже по потоку. Для получения дополнительной информации смотрите Устранение ненужных служебных функций с использованием заданных минимальных и максимальных значений.

Как включить оптимизацию

  1. В диалоговом окне Параметров конфигурации установите Code Generation > System target file, чтобы выбрать Embedded Real-Time (ERT) конечный объект (требуется лицензия Embedded Coder).

  2. Задайте проектные минимальные и максимальные значения для сигналов и параметров в вашей модели, используя советы в How to Configure Your Model.

  3. Выберите Optimization > Advanced parameters > Optimize using the specified minimum and maximum values параметр конфигурации.

Ограничения

  • Эта оптимизация не происходит для:

    • Операции с несколькими словами

    • Типы данных с фиксированной точкой с масштабированием откоса и смещения

    • Сложение, если длина дроби не равна нулю

  • Эта оптимизация не учитывает минимальные и максимальные значения для:

    • Merge блочные входы. Чтобы решить эту проблему, используйте Simulink.Signal объект на выходе блока Merge и задайте область значений на этом объекте.

    • Элементы шины.

    • Условно выполненные подсистемы (такие как триггируемые подсистемы) выходы блоков, которые непосредственно соединяются с блоком Outport.

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

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

  • Если ваша модель содержит несколько образцов переиспользуемой подсистемы, и каждый образец использует входные сигналы с различными заданными минимальными и максимальными значениями, эта оптимизация может привести к различным сгенерированным кодам для каждой подсистемы, поэтому повторное использование кода не происходит. Без этой оптимизации программное обеспечение Simulink Coder™ генерирует код один раз для подсистемы и использует этот код среди нескольких образцов подсистемы.

Устранение ненужных служебных функций с помощью заданных минимальных и максимальных значений

В этом примере показано, как программное обеспечение Fixed-Point Designer использует входную область значений для операции деления, чтобы определить, может ли оно исключить ненужные служебные функции из сгенерированного кода. Он использует fxpdemo_min_max_optimization модель. Во-первых, вы генерируете код, не используя заданные минимальное и максимальное значения, чтобы увидеть, что сгенерированный код содержит служебные функции, чтобы убедиться, что деление по нулю не происходит. Затем включите оптимизацию и снова сгенерируйте код. При оптимизации сгенерированный код не содержит служебной функции, потому что это не обязательно для входа области значений.

Сгенерируйте код, не используя минимальное и максимальное значения

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

  1. Запустите fxpdemo_min_max_optimization пример.

  2. В окне примера дважды нажмите кнопку View Optimization Configuration.

    Откроется панель Оптимизация (Optimization) диалогового окна Параметры конфигурации (Configuration Parameters).

    Обратите внимание, что параметр Optimize using specified minimum and maximum values не выбран.

  3. Дважды кликните кнопку «Сгенерировать код».

    Появится отчет генерации кода.

  4. В модели щелкните правой кнопкой мыши по Division with increased fraction length output type блок.

    Появится контекстное меню.

  5. В контекстном меню выберите C/C++ Code > Navigate To C/C++ Code.

    В отчете о генерации кода подсвечивается код, сгенерированный для этого блока. Сгенерированный код включает вызов к div_repeat_u32 Служебная функция.

    rtY.Out3 = div_repeat_u32((uint32_T)rtU.In5 << 16, 
      (uint32_T)rtU.In6, 1U);

  6. Нажмите на div_repeat_u32 ссылка для просмотра служебной функции, которая содержит код для обработки деления на нули.

Сгенерируйте код с использованием минимальных и максимальных значений

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

  1. Дважды кликните маркированный Inport блок 5 чтобы открыть диалоговое окно параметров блоков.

  2. В диалоговом окне параметров блоков выберите панель Signal Attributes и отметьте, что:

    • Значение Minimum для этого сигнала 1.

    • Значение Maximum для этого сигнала 100.

  3. Нажмите кнопку OK, чтобы закрыть диалоговое окно.

  4. Дважды кликните кнопку View Optimization Configuration.

    Откроется панель Оптимизация (Optimization) диалогового окна Параметры конфигурации (Configuration Parameters).

  5. На этой панели выберите параметр Optimize using specified minimum and maximum values и нажмите Apply.

  6. Дважды кликните кнопку «Сгенерировать код».

    Появится отчет генерации кода.

  7. В модели щелкните правой кнопкой мыши по Division with increased fraction length output type блок.

    Появится контекстное меню.

  8. В контекстном меню выберите C/C++ Code > Navigate To C/C++ Code.

    В отчете о генерации кода подсвечивается код, сгенерированный для этого блока. На этот раз сгенерированный код реализует деление с операцией сдвига и нет служебной функции деления.

    tmp = rtU.In6;
    rtY.Out3 = (uint32_T)tmp == 
      (uint32_T)0 ? MAX_uint32_T : ((uint32_T)rtU.In5 << 17) /
        (uint32_T)tmp;

Изменение заданных минимального и максимального значений

Наконец, измените минимальное и максимальное значения для первого входа в операцию деления так, чтобы его входная область значений была слишком большим, чтобы гарантировать, что значение не переполнится при сдвиге. Здесь вы не можете переместить 16-битное число 17 бит вправо, не переполняя 32-битный контейнер. Сгенерируйте код для операции деления, снова с учетом минимального и максимального значений. С этими входными областями значений сгенерированный код включает в себя служебную функцию деления, чтобы убедиться, что переполнение не происходит.

  1. Дважды кликните маркированный Inport блок 5 чтобы открыть диалоговое окно параметров блоков.

  2. В диалоговом окне параметров блоков выберите панель Signal Attributes и установите значение Maximum равным 40000, затем нажмите кнопку OK, чтобы закрыть диалоговое окно.

  3. Дважды кликните кнопку «Сгенерировать код».

    Появится отчет генерации кода.

  4. В модели щелкните правой кнопкой мыши по Division with increased fraction length output type блок.

    Появится контекстное меню.

  5. В контекстном меню выберите C/C++ Code > Navigate To C/C++ Code.

    В отчете о генерации кода подсвечивается код, сгенерированный для этого блока. Сгенерированный код включает вызов к div_repeat_32 Служебная функция.

    rtY.Out3 = div_repeat_u32((uint32_T)rtU.In5 << 16, 
      (uint32_T)rtU.In6, 1U);