MATLAB CODER в сгенерированном коде

Чтобы улучшить скорость выполнения и использование памяти сгенерированного кода, MATLAB® Coder™ представляет следующие оптимизации:

Постоянное складывание

Когда это возможно, генератор кода оценивает выражения в коде MATLAB, которые включают только константы времени компиляции. В сгенерированном коде эти выражения заменяются результатом вычислений. Такое поведение известно как постоянное складывание. Из-за постоянного складывания сгенерированный код не должен оценивать константы во время выполнения.

В следующем примере показан код MATLAB, который постоянно складывается во время генерации кода. Функция MultiplyConstant умножает каждый элемент матрицы на скаляр константу. Функция оценивает эту константу, используя продукт трех констант времени компиляции, a, b, и c.

function out=MultiplyConstant(in) %#codegen
 a=pi^4;
 b=1/factorial(4);
 c=exp(-1);
 out=in.*(a*b*c);
end

Генератор кода оценивает выражения, включающие константы времени компиляции, a, b, и c. Это заменяет эти выражения результатом анализа в сгенерированном коде.

Постоянное складывание может происходить, когда выражения включают только скаляры. Чтобы явным образом применить постоянное складывание выражений в других случаях, используйте coder.const функция. Для получения дополнительной информации смотрите Fold Function Calls into Constants.

Управление Постоянным Складыванием

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

  • В командной строке создайте объект строения для генерации кода. Установите свойство ConstantFoldingTimeout к значению, которое вы хотите.

    cfg=coder.config('lib');
    cfg.ConstantFoldingTimeout = 200;
  • Используя приложение, в диалоговом окне настроек проекта, на вкладке All Settings, установите Constant folding timeout поля на то значение, которое вы хотите.

Циклическое слияние

Когда это возможно, генератор кода запирает последовательные циклы с таким же количеством запусков в один цикл в сгенерированном коде. Эта оптимизация уменьшает накладные расходы по циклу.

Следующий код содержит последующие циклы, которые объединяются во время генерации кода. Функция SumAndProduct вычисляет сумму и продукт элементов массива Arr. Функция использует два отдельных цикла, чтобы вычислить сумму y_f_sum и y_f_prod продукта.

function [y_f_sum,y_f_prod] = SumAndProduct(Arr) %#codegen
  y_f_sum = 0;
  y_f_prod = 1;
  for i = 1:length(Arr)
     y_f_sum = y_f_sum+Arr(i);
  end
  for i = 1:length(Arr)
     y_f_prod = y_f_prod*Arr(i);
  end

Код, сгенерированный из этого кода MATLAB, оценивает сумму и продукт в одном цикле.

Последующие матричные операции вместе взятые

Когда это возможно, генератор кода преобразует последующие матричные операции в коде MATLAB в операцию с одним циклом в сгенерированном коде. Эта оптимизация уменьшает накладные расходы по избыточному циклу, участвующие в выполнении матричных операций в отдельных циклах.

Следующий пример содержит код, где происходят последующие матричные операции. Функция ManipulateMatrix умножает каждый элемент массива матрицы Mat с factor. К каждому элементу в результате функция затем добавляет shift:

function Res=ManipulateMatrix(Mat,factor,shift)
  Res=Mat*factor;
  Res=Res+shift;
end

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

Устранение недостижимого кода

Когда это возможно, генератор кода подавляет генерацию кода из недоступных процедур в коде MATLAB. Например, если ветвь if, elseif, else оператор недоступен, код не генерируется для этой ветви.

Следующий пример содержит недостижимый код, который устраняется во время генерации кода. Функция SaturateValue возвращает значение, основанное на области значений его входных x.

function y_b = SaturateValue(x) %#codegen
  if x>0
    y_b = x;
  elseif x>10 %This is redundant
    y_b = 10;
  else
    y_b = -x;
 end

Вторая ветвь if, elseif, else оператор недоступен. Если переменная x больше 10, также больше 0. Поэтому первая ветвь выполняется в выборе второй ветви.

MATLAB Coder не генерирует код для недоступной второй ветви.

memcpy Вызовы

Чтобы оптимизировать сгенерированный код, который копирует последовательные элементы массива, генератор кода пытается заменить код на memcpy вызов. A memcpy вызов может быть более эффективным, чем код, например for-цикл или несколько последовательных назначений элементов.

См. Оптимизация мемкпи.

memset Вызовы

Чтобы оптимизировать сгенерированный код, который присваивает буквальную константу последовательным элементам массива, генератор кода пытается заменить код на memset вызов. A memset вызов может быть более эффективным, чем код, например for-цикл или несколько последовательных назначений элементов.

Смотрите Оптимизацию мемсета.