Удаление копий данных путем переупорядочивания Блоков операций в сгенерированном коде

В этом примере показано, как удалить копии данных путем изменения параметра Optimize block order in the generated code из off на Improved Execution Speed. Изменение этой настройки указывает на генератор кода, чтобы переупорядочить операции блока, где это возможно, чтобы удалить копии данных. Этот параметр находится в диалоговом окне Параметров конфигурации. Эта оптимизация сохраняет потребление ОЗУ и ПЗУ.

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

В модель ex_optimizeblockorder, сигнал, который покидает блок Sum, входит в блок Subtract и блок Concatenate. Сигнал, который покидает блок Subtract, входит в блок Product и блок Sum of Elements.

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

На изображении показана модель ex_optimizeblockorder после сборки модели. Красные цифры указывают порядок блоков по умолчанию в сгенерированном коде. Блок Вычитание выполняется перед блоком Конкатенация. Блок Product выполняется перед блоком Sum of Elements.

Просмотрите сгенерированный код без оптимизации. Вот ex_optimizeblockorder_step функция.

/* Model step function */
void ex_optimizeblockorder_step(void)
{
  real_T rtb_Sum2x3[6];
  int32_T i;
  real_T rtb_Sum2x3_d;
  real_T rtb_Subtract;

  /* Sum: '<Root>/SumOfElements' */
  rtY.Out2 = -0.0;
  for (i = 0; i < 6; i++) {
    /* Sum: '<Root>/Sum2x3' incorporates:
     *  Inport: '<Root>/In1'
     *  Inport: '<Root>/In2'
     */
    rtb_Sum2x3_d = rtU.In1[i] + rtU.In2;

    /* Sum: '<Root>/Subtract' incorporates:
     *  Inport: '<Root>/In3'
     */
    rtb_Subtract = rtb_Sum2x3_d - rtU.In3;

    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In4'
     *  Product: '<Root>/Product'
     */
    rtY.Out1[i] = rtU.In4[i] * rtb_Subtract;

    /* Sum: '<Root>/Sum2x3' */
    rtb_Sum2x3[i] = rtb_Sum2x3_d;

    /* Sum: '<Root>/SumOfElements' */
    rtY.Out2 += rtb_Subtract;
  }

  /* Concatenate: '<Root>/MatrixConcat ' */
  for (i = 0; i < 3; i++) {
    /* Outport: '<Root>/Out3' incorporates:
     *  Inport: '<Root>/In5'
     */
    rtY.Out3[i << 2] = rtb_Sum2x3[i << 1];
    rtY.Out3[2 + (i << 2)] = rtU.In5[i << 1];
    rtY.Out3[1 + (i << 2)] = rtb_Sum2x3[(i << 1) + 1];
    rtY.Out3[3 + (i << 2)] = rtU.In5[(i << 1) + 1];
  }

  /* End of Concatenate: '<Root>/MatrixConcat ' */
}

С порядком по умолчанию сгенерированный код содержит три буфера, rtb_Sum2x3[6], rtb_Sum2x3_d, и rtb_Subtract. Сгенерированный код содержит эти временные переменные и связанные копии данных, потому что блок Matrix Concatenate должен использовать выход из блока Sum, а блок Sum of Elements должен использовать выход из блока Subtract.

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

На изображении показан ex_optimizeblockorder модель после установки параметра Optimize block operation order in the generated code равной Improved Execution Speed и создание модели. Блок Subtract выполняется после блока Concatenate. Блок Product выполняется после блока Sum of Elements.

В оптимизированном коде три буфера rtb_Sum2x3[6], rtb_Sum2x3_d, и rtb_Subtract и связанные с ними копии данных исчезли. Сгенерированный код не требует, чтобы эти временные переменные удерживали выходы блоков Sum и Extract, потому что блок Вычитание выполняется после блока Concatenate, а блок Product - после блока Sum of Elements.

/* Model step function */
void ex_optimizeblockorder_step(void)
{
  int32_T i;

  /* Sum: '<Root>/Sum2x3' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   */
  for (i = 0; i < 6; i++) {
    rtY.Out1[i] = rtU.In1[i] + rtU.In2;
  }

  /* End of Sum: '<Root>/Sum2x3' */

  /* Concatenate: '<Root>/MatrixConcat ' */
  for (i = 0; i < 3; i++) {
    /* Outport: '<Root>/Out3' incorporates:
     *  Inport: '<Root>/In5'
     */
    rtY.Out3[i << 2] = rtY.Out1[i << 1];
    rtY.Out3[2 + (i << 2)] = rtU.In5[i << 1];
    rtY.Out3[1 + (i << 2)] = rtY.Out1[(i << 1) + 1];
    rtY.Out3[3 + (i << 2)] = rtU.In5[(i << 1) + 1];
  }

  /* End of Concatenate: '<Root>/MatrixConcat ' */

  /* Sum: '<Root>/SumOfElements' */
  rtY.Out2 = -0.0;
  for (i = 0; i < 6; i++) {
    /* Sum: '<Root>/Subtract' incorporates:
     *  Inport: '<Root>/In3'
     */
    rtY.Out1[i] -= rtU.In3;

    /* Sum: '<Root>/SumOfElements' */
    rtY.Out2 += rtY.Out1[i];

    /* Outport: '<Root>/Out1' incorporates:
     *  Inport: '<Root>/In4'
     *  Product: '<Root>/Product'
     */
    rtY.Out1[i] *= rtU.In4[i];
  }
}

Чтобы реализовать повторное использование буфера, генератор кода не нарушает заданные пользователем приоритеты блоков.

См. также

Похожие темы