Преобразуйте копии данных в присвоения указателя

Генератор кода оптимизирует сгенерированный код для векторных присвоений сигнала путем попытки заменить присвоения управляемого элемента цикла for и вызовы функции memcpy с присвоениями указателя. Присвоения указателя избегают дорогих копий данных. Поэтому они используют меньше стекового пространства и предлагают более быструю скорость выполнения, чем присвоения управляемого элемента цикла for и вызовы функции memcpy. Если вы присваиваете большие наборы данных векторным сигналам, эта оптимизация может привести к существенным улучшениям, чтобы закодировать эффективность.

Сконфигурируйте модель, чтобы оптимизировать сгенерированный код для векторных присвоений сигнала

Применять эту оптимизацию:

  1. Проверьте, что ваша цель поддерживает функцию memcpy.

  2. Определите, использует ли ваша модель векторные присвоения сигнала (такие как Y=expression), чтобы переместить большие объемы данных. Например, ваша модель могла использовать Селекторный блок, чтобы выбрать входные элементы из вектора, матрицы или сигнала мультиразмерности.

  3. На панели Оптимизации Использование memcpy для векторного параметра присвоения, который включен по умолчанию, включает связанный порог Memcpy (байты) параметр.

  4. Исследуйте установку порога Memcpy (байты). По умолчанию это задает 64 байта как минимальный размер массивов, для которого вызовы функции memcpy или присвоения указателя могут заменить циклы for в сгенерированном коде. На основе размеров массивов в векторных присвоениях вашего приложения сигнала и факторов целевого окружения на пороговом выборе, принимают значение по умолчанию или задают другой размер массивов.

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

Считайте следующую модель названной rtwdemo_pointer_conversion. Эта модель использует блок switch, чтобы присвоить данные векторному сигналу. Этот сигнал затем питается в блок Селектора Шины.

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

  1. В диалоговом окне Configuration Parameters очистите Использование memcpy для векторного параметра присвоения.

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

  3. Нажмите Ctrl+B, чтобы сгенерировать код.

### Starting build procedure for model: rtwdemo_pointer_conversion
### Successful completion of build procedure for model: rtwdemo_pointer_conversion

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

/* Model step function */
void rtwdemo_pointer_conversion_step(void)
{
  int16_T rtb_dataX[100];
  int16_T rtb_dataY[100];
  int32_T i;

  /* Switch: '<Root>/Switch' incorporates:
   *  Constant: '<Root>/Constant'
   *  Constant: '<Root>/Constant1'
   *  Constant: '<Root>/Constant2'
   *  Constant: '<Root>/Constant3'
   *  Inport: '<Root>/In1'
   */
  for (i = 0; i < 100; i++) {
    if (rtU.In1) {
      rtb_dataX[i] = rtCP_Constant_Value[i];
      rtb_dataY[i] = rtCP_Constant1_Value[i];
    } else {
      rtb_dataX[i] = rtCP_Constant2_Value[i];
      rtb_dataY[i] = rtCP_Constant3_Value[i];
    }
  }

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

  /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates:
   *  Inport: '<Root>/In2'
   *  Outport: '<Root>/Out1'
   */
  /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic'
   * Input0  Data Type:  Integer        S16
   * Input1  Data Type:  Integer        S16
   * Input2  Data Type:  Integer        S16
   * Output0 Data Type:  Integer        S16
   * Lookup Method: Linear_Endpoint
   *
   */
  LookUp_S16_S16( &(rtY.Out1), &rtb_dataY[0], rtU.In2, &rtb_dataX[0], 99U);
}

Без оптимизации сгенерированный код содержит присвоения управляемого элемента цикла for.

Включите оптимизацию и сгенерируйте код

  1. В диалоговом окне Configuration Parameter выберите Use memcpy для векторного параметра присвоения.

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

### Starting build procedure for model: rtwdemo_pointer_conversion
### Successful completion of build procedure for model: rtwdemo_pointer_conversion

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

/* Model step function */
void rtwdemo_pointer_conversion_step(void)
{
  const int16_T *rtb_dataX_0;
  const int16_T *rtb_dataY_0;

  /* Inport: '<Root>/In1' */
  if (rtU.In1) {
    /* Switch: '<Root>/Switch' incorporates:
     *  Constant: '<Root>/Constant'
     *  Constant: '<Root>/Constant1'
     */
    rtb_dataX_0 = &rtCP_Constant_Value[0];
    rtb_dataY_0 = &rtCP_Constant1_Value[0];
  } else {
    /* Switch: '<Root>/Switch' incorporates:
     *  Constant: '<Root>/Constant2'
     *  Constant: '<Root>/Constant3'
     */
    rtb_dataX_0 = &rtCP_Constant2_Value[0];
    rtb_dataY_0 = &rtCP_Constant3_Value[0];
  }

  /* End of Inport: '<Root>/In1' */

  /* S-Function (sfix_look1_dyn): '<Root>/Lookup Table Dynamic' incorporates:
   *  Inport: '<Root>/In2'
   *  Outport: '<Root>/Out1'
   */
  /* Dynamic Look-Up Table Block: '<Root>/Lookup Table Dynamic'
   * Input0  Data Type:  Integer        S16
   * Input1  Data Type:  Integer        S16
   * Input2  Data Type:  Integer        S16
   * Output0 Data Type:  Integer        S16
   * Lookup Method: Linear_Endpoint
   *
   */
  LookUp_S16_S16( &(rtY.Out1), &rtb_dataY_0[0], rtU.In2, &rtb_dataX_0[0], 99U);
}

Поскольку установка порога Memcpy (байты), которые параметр ниже размеров массивов в сгенерированном коде, оптимизированный код, содержит присвоения указателя для векторных присвоений сигнала.

Смотрите также

|

Похожие темы