Сверните выражения

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

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

Модель в качестве примера

model = 'rtwdemo_slexprfold';
open_system(model);

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

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

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

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

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

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

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

С выражением, сворачивающимся прочь, в 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)
{
  boolean_T rtb_LogicalOperator;
  boolean_T rtb_RelationalOperator;
  real_T rtb_Gain;

  /* 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' */
    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 (2-D)' incorporates:
     *  Inport: '<Root>/In3'
     *  Inport: '<Root>/In4'
     */
    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');

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

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

Следующее является фрагментом 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.