Оптимизация сгенерированного кода путем консолидации избыточных операторов if-else

Этот пример показывает, как оптимизировать сгенерированный код путем объединения if-else операторы, которые имеют одно и то же условие. Эта оптимизация:

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

  • Уменьшает размер кода.

  • Уменьшает потребление оперативной памяти.

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

Пример

rtwdemo_controlflow_opt модели содержит три блока Switch. Блок Constant обеспечивает вход управления для блоков Switch. Переменная с именем Cond определяет значение блока Constant.

model = 'rtwdemo_controlflow_opt';
open_system(model);

Сгенерируйте код

Создайте временную папку для процесса сборки и проверки.

currentDir = pwd;
[~,cgDir] = rtwdemodir();

Создайте модель.

slbuild(model)
### Starting build procedure for: rtwdemo_controlflow_opt
### Successful completion of build procedure for: rtwdemo_controlflow_opt

Build Summary

Top model targets built:

Model                    Action                       Rebuild Reason                                    
========================================================================================================
rtwdemo_controlflow_opt  Code generated and compiled  Code generation information file does not exist.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 9.6016s

Эти линии rtwdemo_controlflow_opt.c код показывает, что в сгенерированном коде два if-else операторы и один else-if оператор представляет три блока Switch.

cfile = fullfile(cgDir,'rtwdemo_controlflow_opt_ert_rtw',...
    'rtwdemo_controlflow_opt.c');
rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_controlflow_opt_step(void)
{
  /* Switch: '<Root>/Switch3' incorporates:
   *  Constant: '<Root>/Const'
   *  Switch: '<Root>/Switch2'
   */
  if (Cond) {
    /* Switch: '<Root>/Switch1' */
    if (Cond) {
      /* Outport: '<Root>/Out1' incorporates:
       *  Inport: '<Root>/In1'
       */
      rtY.Out1 = rtU.In1;
    } else {
      /* Outport: '<Root>/Out1' incorporates:
       *  Inport: '<Root>/In2'
       */
      rtY.Out1 = rtU.In2;
    }

    /* End of Switch: '<Root>/Switch1' */
  } else if (Cond) {
    /* Switch: '<Root>/Switch2' incorporates:
     *  Inport: '<Root>/In1'
     *  Outport: '<Root>/Out1'
     */
    rtY.Out1 = rtU.In1;
  } else {
    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In2'
     */
    rtY.Out1 = rtU.In2;
  }

  /* End of Switch: '<Root>/Switch3' */
}

Включите оптимизацию

  1. Откройте диалоговое окно Параметры конфигурации.

  2. На панели Code generation- > Code Style снимите флажок Сохранить выражение условия в операторе if. Этот параметр включен по умолчанию.

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

set_param(model, 'PreserveIfCondition', 'off');

Сгенерируйте код с оптимизацией

В оптимизированном коде генератор кода консолидирует два if-else операторы и один else-if оператор в один if-else оператор. Генератор кода консолидирует эти операторы, потому что все они имеют одно и то же условие. Отсутствует промежуточный код, который влияет на результаты этих операторов.

Создайте модель.

slbuild(model)
### Starting build procedure for: rtwdemo_controlflow_opt
### Successful completion of build procedure for: rtwdemo_controlflow_opt

Build Summary

Top model targets built:

Model                    Action                       Rebuild Reason                   
=======================================================================================
rtwdemo_controlflow_opt  Code generated and compiled  Generated code was out of date.  

1 of 1 models built (0 models already up to date)
Build duration: 0h 0m 9.4425s

Вот rtwdemo_controlflow_opt.c оптимизированный код.

rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_controlflow_opt_step(void)
{
  /* Switch: '<Root>/Switch1' incorporates:
   *  Constant: '<Root>/Const'
   *  Switch: '<Root>/Switch3'
   */
  if (Cond) {
    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In1'
     */
    rtY.Out1 = rtU.In1;
  } else {
    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In2'
     */
    rtY.Out1 = rtU.In2;
  }

  /* End of Switch: '<Root>/Switch1' */
}

Закройте модель и очистите.

bdclose(model)
rtwdemoclean;
cd(currentDir)

См. также

Похожие темы