exponenta event banner

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

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

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

В модели ex_optimizeblockorderсигнал, выходящий из блока Sum, поступает в блок Вычитания и блок Конкатената. Сигнал, выходящий из блока «Вычитание», поступает в блок «Произведение» и блок «Сумма элементов».

Создание кода без оптимизации

На рисунке показана модель 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 в сгенерированном параметре кода на Improved Execution Speed и построение модели. Блок вычитания выполняется после блока конкатенации. Блок Product выполняется после блока Sum of Elements.

В оптимизированном коде три буфера rtb_Sum2x3[6], rtb_Sum2x3_d, и rtb_Subtract и их соответствующие копии данных исчезли. Сгенерированный код не требует, чтобы эти временные переменные содержали выходные данные блоков Sum и Subtract, поскольку блок Subtract выполняется после блока 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];
  }
}

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

См. также

Связанные темы