Складывайте выражения

Складывание выражения оптимизирует код, чтобы минимизировать расчет промежуточных результатов на выходах блоков и хранение таких результатов во временных буферах или переменных. Когда свертка выражения включена, генератор кода сворачивает (складывает) расчеты в одно выражение, вместо того, чтобы генерировать отдельные операторы кода и объявления хранилища для каждого блока в модели. Большинство блоков Simulink поддерживают складывание выражений.

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

Пример модели

model = 'rtwdemo_slexprfold';
open_system(model);

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

Складывание выражения доступно только, когда параметр повторного использования памяти сигнала установлен в on, потому что складывание выражения работает только с выражениями с локальными переменными. Параметры повторное использование памяти и Eliminate supertuous local variables (expression folding) включены по умолчанию. Очистите параметр Устранить лишние локальные переменные (складывание выражения) или введите следующую команду в Командном Окне MATLAB, чтобы выключить параметр:

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

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

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

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

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

Build Summary

Top model targets built:

Model               Action                       Rebuild Reason                                    
===================================================================================================
rtwdemo_slexprfold  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 6.3738s

С выключенным выражением, в rtwdemo_slexprfold.c файл, существуют отдельные операторы кода до и в операции Блока switch.

cfile = fullfile(cgDir,'rtwdemo_slexprfold_grt_rtw','rtwdemo_slexprfold.c');
rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_slexprfold_step(void)
{
  real_T rtb_Gain;
  boolean_T rtb_LogicalOperator;
  boolean_T rtb_RelationalOperator;

  /* RelationalOperator: '<Root>/Relational Operator1' incorporates:
   *  Constant: '<Root>/Constant'
   *  Inport: '<Root>/In2'
   */
  rtb_LogicalOperator = (rtwdemo_slexprfold_P.UPPER >= rtwdemo_slexprfold_U.In2);

  /* RelationalOperator: '<Root>/Relational Operator' incorporates:
   *  Constant: '<Root>/Constant1'
   *  Inport: '<Root>/In2'
   */
  rtb_RelationalOperator = (rtwdemo_slexprfold_U.In2 <=
    rtwdemo_slexprfold_P.LOWER);

  /* Logic: '<Root>/Logical Operator' */
  rtb_LogicalOperator = (rtb_LogicalOperator || rtb_RelationalOperator);

  /* Switch: '<Root>/Switch' */
  if (rtb_LogicalOperator) {
    /* Gain: '<Root>/Gain' incorporates:
     *  Inport: '<Root>/In1'
     */
    rtb_Gain = 2.0 * rtwdemo_slexprfold_U.In1;

    /* Lookup_n-D: '<Root>/Look-Up Table' incorporates:
     *  Gain: '<Root>/Gain'
     */
    rtwdemo_slexprfold_Y.Out1 = look1_binlx(rtb_Gain,
      rtwdemo_slexprfold_P.T1Break, rtwdemo_slexprfold_P.T1Data, 10U);
  } else {
    /* Lookup_n-D: '<Root>/Look-Up Table' incorporates:
     *  Inport: '<Root>/In3'
     *  Inport: '<Root>/In4'
     *  Lookup_n-D: '<Root>/Look-Up Table (2-D)'
     */
    rtwdemo_slexprfold_Y.Out1 = look2_binlx(rtwdemo_slexprfold_U.In3,
      rtwdemo_slexprfold_U.In4, rtwdemo_slexprfold_P.T2Break,
      rtwdemo_slexprfold_P.T2Break, rtwdemo_slexprfold_P.T2Data,
      rtCP_LookUpTable2D_maxIndex, 3U);
  }

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

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

Введите следующую команду, чтобы включить складывание выражения:

set_param(model, 'ExpressionFolding','on');

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

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

Build Summary

Top model targets built:

Model               Action                       Rebuild Reason                   
==================================================================================
rtwdemo_slexprfold  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 5.4258s

Ниже представлен фрагмент rtwdemo_slexprfold.c. В оптимизированном коде генератор кода складывает все расчеты в операцию Блока switch.

rtwdemodbtype(cfile,'/* Model step', '/* Model initialize', 1, 0);
/* Model step function */
void rtwdemo_slexprfold_step(void)
{
  /* Switch: '<Root>/Switch' incorporates:
   *  Constant: '<Root>/Constant'
   *  Constant: '<Root>/Constant1'
   *  Inport: '<Root>/In2'
   *  Logic: '<Root>/Logical Operator'
   *  RelationalOperator: '<Root>/Relational Operator'
   *  RelationalOperator: '<Root>/Relational Operator1'
   */
  if ((rtwdemo_slexprfold_P.UPPER >= rtwdemo_slexprfold_U.In2) ||
      (rtwdemo_slexprfold_U.In2 <= rtwdemo_slexprfold_P.LOWER)) {
    /* Outport: '<Root>/Out1' incorporates:
     *  Gain: '<Root>/Gain'
     *  Inport: '<Root>/In1'
     *  Lookup_n-D: '<Root>/Look-Up Table'
     */
    rtwdemo_slexprfold_Y.Out1 = look1_binlx(2.0 * rtwdemo_slexprfold_U.In1,
      rtwdemo_slexprfold_P.T1Break, rtwdemo_slexprfold_P.T1Data, 10U);
  } else {
    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In3'
     *  Inport: '<Root>/In4'
     *  Lookup_n-D: '<Root>/Look-Up Table (2-D)'
     */
    rtwdemo_slexprfold_Y.Out1 = look2_binlx(rtwdemo_slexprfold_U.In3,
      rtwdemo_slexprfold_U.In4, rtwdemo_slexprfold_P.T2Break,
      rtwdemo_slexprfold_P.T2Break, rtwdemo_slexprfold_P.T2Data,
      rtCP_LookUpTable2D_maxIndex, 3U);
  }

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

Закройте модель и отчет о генерации кода.

bdclose(model)
rtwdemoclean;
cd(currentDir)

Для примера, в котором выражения кода складываются между Simulink и Stateflow, откройте эту модель rtwdemo_sfexprfold.