Удалите код, который принимает меры против исключений деления для данных фиксированной точки и Целых чисел

Оптимизируйте сгенерированный код путем удаления кода, который защищает от деления на нуль и переполнения в делении операции INT_MIN/-1 для данных фиксированной точки и целых чисел. Если вы уверены, что эти арифметические исключения не происходят во время выполнения программы, включают эту оптимизацию, но это может привести к частному, которое не может быть представлено.

Эта оптимизация:

  • Скорость выполнения увеличений.

  • Результаты в меньшем коде, таким образом, уменьшающем потребление ROM.

Риски

Когда вы выбираете параметр NoFixptDivByZeroProtection, генератор кода удаляет код, который защищает от следующих ошибок:

  • Когда вы делитесь на нуль, это не определено и приводит к ошибке периода выполнения в сгенерированном коде.

  • Когда вы делите минимальное представимое значение целого числа со знаком отрицательным, идеальный результат равен максимальному представимому значению плюс одно (INT_MAX + 1), который не является представимым. Это исключение может заставить приложение неожиданно останавливаться или отказывать во времени выполнения.

ПРИМЕЧАНИЕ: Если вы включаете эту оптимизацию, возможно, что результаты симуляции и следуют из сгенерированного кода, не находятся в поразрядном соглашении. Этот пример требует лицензии Embedded Coder®.

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

В модели rtwdemo_nzcheck, два сигнала типа канал int8 в блок деления.

model = 'rtwdemo_nzcheck';
open_system(model);

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

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

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

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

set_param(model, 'NoFixptDivByZeroProtection', 'off');
rtwbuild(model);
### Starting build procedure for model: rtwdemo_nzcheck
### Successful completion of code generation for model: rtwdemo_nzcheck

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

cfile = fullfile(cgDir,'rtwdemo_nzcheck_ert_rtw','rtwdemo_nzcheck.c');
rtwdemodbtype(cfile,'/* Real-time model','/* Model initialize function',1, 1);
/* Real-time model */
RT_MODEL_rtwdemo_nzcheck rtwdemo_nzcheck_M_;
RT_MODEL_rtwdemo_nzcheck *const rtwdemo_nzcheck_M = &rtwdemo_nzcheck_M_;
int32_T div_s32(int32_T numerator, int32_T denominator)
{
  int32_T quotient;
  uint32_T tempAbsQuotient;
  if (denominator == 0) {
    quotient = numerator >= 0 ? MAX_int32_T : MIN_int32_T;

    /* Divide by zero handler */
  } else {
    tempAbsQuotient = (numerator < 0 ? ~(uint32_T)numerator + 1U : (uint32_T)
                       numerator) / (denominator < 0 ? ~(uint32_T)denominator +
      1U : (uint32_T)denominator);
    quotient = (numerator < 0) != (denominator < 0) ? -(int32_T)tempAbsQuotient :
      (int32_T)tempAbsQuotient;
  }

  return quotient;
}

/* Model step function */
void rtwdemo_nzcheck_step(void)
{
  /* Product: '<Root>/Divide' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   */
  Y = div_s32(U1, U2);
}

Включите оптимизацию

  1. Откройте диалоговое окно Configuration Parameters.

  2. На панели Оптимизации выберите код Remove, который защищает от арифметических исключений деления.

Также можно использовать API командной строки, чтобы включить оптимизацию:

set_param(model, 'NoFixptDivByZeroProtection', 'on');

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

Оптимизированный код не содержит код, который проверяет на то, имеет ли делитель значение нуля.

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

rtwbuild(model);
### Starting build procedure for model: rtwdemo_nzcheck
### Successful completion of code generation for model: rtwdemo_nzcheck

Следующее является фрагментом rtwdemo_nzcheck.c. Код, который защищает от арифметических исключений деления, не находится в сгенерированном коде.

rtwdemodbtype(cfile,'/* Real-time model','/* Model initialize function',1, 1);
/* Real-time model */
RT_MODEL_rtwdemo_nzcheck rtwdemo_nzcheck_M_;
RT_MODEL_rtwdemo_nzcheck *const rtwdemo_nzcheck_M = &rtwdemo_nzcheck_M_;

/* Model step function */
void rtwdemo_nzcheck_step(void)
{
  /* Product: '<Root>/Divide' incorporates:
   *  Inport: '<Root>/In1'
   *  Inport: '<Root>/In2'
   */
  Y = U1 / U2;
}

Закройте отчет генерации кода и модель.

bdclose(model)
rtwdemoclean;
cd(currentDir)

Дополнительная информация

Существует несколько других факторов, которые могут влиять на внешний вид сгенерированного кода для операций деления. Сгенерированный код для блоков, содержащих код MATLAB® с операциями деления целочисленной или фиксированной точки, отличается от встроенного блока Divide в Simulink®. Чтобы сбалансировать эффективность и семантику фиксированной точки и целочисленных делений в этих блоках, используйте объекты fi и установите свойства fimath соответствовать вашим потребностям, и требует лицензии Fixed-Point Designer™. Округление и режимы переполнения также влияет на размер и эффективность сгенерированного кода.

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

Похожие темы