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

Генератор кода оптимизирует сгенерированный код для векторных присвоений сигнала путем попытки заменить 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: rtwdemo_pointer_conversion
### Successful completion of build procedure for: 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 generated from: '<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 generated from: '<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: rtwdemo_pointer_conversion
### Successful completion of build procedure for: 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 generated from: '<Root>/Switch' incorporates:
     *  Constant: '<Root>/Constant'
     */
    rtb_dataX_0 = &rtCP_Constant_Value[0];

    /* Switch generated from: '<Root>/Switch' incorporates:
     *  Constant: '<Root>/Constant1'
     */
    rtb_dataY_0 = &rtCP_Constant1_Value[0];
  } else {
    /* Switch generated from: '<Root>/Switch' incorporates:
     *  Constant: '<Root>/Constant2'
     */
    rtb_dataX_0 = &rtCP_Constant2_Value[0];

    /* Switch generated from: '<Root>/Switch' incorporates:
     *  Constant: '<Root>/Constant3'
     */
    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 (байты), которые параметр ниже размеров массивов в сгенерированном коде, оптимизированный код, содержит присвоения указателя для векторных присвоений сигнала.

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

|

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте