Разверните for- цикл путем создания копии тела цикла для каждой итерации цикла
coder.unroll() разворачивает for- цикл. coder.unroll вызов должен быть на линии отдельно сразу предшествованием for- цикл, который это разворачивает.
Вместо того, чтобы произвести a for- цикл в сгенерированном коде, развертывание цикла производит копию for- тело цикла для каждой итерации цикла. В каждой итерации индекс цикла становится постоянным. Чтобы развернуть цикл, генератор кода должен смочь определить границы for-цикл.
Для маленьких, жестких циклов разворачивание может улучшать производительность. Однако для больших циклов, разворачивание может значительно увеличить время генерации кода и сгенерировать неэффективный код.
coder.unroll проигнорирован за пределами генерации кода.
for- цикл Произвести копии for- тело цикла в сгенерированном коде, использовать coder.unroll.
В одном файле запишите функцию точки входа call_getrand и локальная функция getrand. getrand разворачивает for- цикл, который присваивает случайные числа n-1 массиву. call_getrand вызовы getrand со значением 3.
function z = call_getrand %#codegen z = getrand(3); end function y = getrand(n) coder.inline('never'); y = zeros(n, 1); coder.unroll(); for i = 1:n y(i) = rand(); end end
Сгенерируйте статическую библиотеку.
codegen -config:lib call_getrand -report
В сгенерированном коде генератор кода производит копию for- тело цикла для каждой из этих трех итераций цикла.
static void getrand(double y[3])
{
y[0] = b_rand();
y[1] = b_rand();
y[2] = b_rand();
}
for- развертывание цикла с флагомЦикл управления, разворачивающий при помощи coder.unroll с flag аргумент.
В одном файле запишите функцию точки входа call_getrand_unrollflag и локальная функция getrand_unrollflag. Когда количество итераций цикла меньше 10, getrand_unrollflag разворачивает for- цикл. call_getrand вызовы getrand со значением 50.
function z = call_getrand_unrollflag %#codegen z = getrand_unrollflag(50); end function y = getrand_unrollflag(n) coder.inline('never'); unrollflag = n < 10; y = zeros(n, 1); coder.unroll(unrollflag) for i = 1:n y(i) = rand(); end end
Сгенерируйте статическую библиотеку.
codegen -config:lib call_getrand_unrollflag -report
Количество итераций не меньше 10. Поэтому генератор кода не разворачивает for- цикл. Это производит for- цикл в сгенерированном коде.
static void getrand_unrollflag(double y[50])
{
int i;
for (i = 0; i < 50; i++) {
y[i] = b_rand();
}
}
for- Циклfunction z = call_getrand %#codegen z = getrand(3); end function y = getrand(n) coder.inline('never'); y = zeros(n, 1); for i = coder.unroll(1:n) y(i) = rand(); end end
for- Развертывание циклаfunction z = call_getrand_unrollflag %#codegen z = getrand_unrollflag(50); end function y = getrand_unrollflag(n) coder.inline('never'); unrollflag = n < 10; y = zeros(n, 1); for i = coder.unroll(1:n, unrollflag) y(i) = rand(); end end
Иногда, генератор кода разворачивает for- цикл даже при том, что вы не используете coder.unroll. Например, если for- цикл индексирует в неоднородный массив ячеек или в varargin или varargout, генератор кода разворачивает цикл. Путем разворачивания цикла генератор кода может определить значение индекса для каждой итерации цикла. Генератор кода использует эвристику, чтобы определить, когда развернуть for- цикл. Если эвристике не удается идентифицировать, что разворачивание гарантировано, или если количество итераций цикла превышает предел, сбои генерации кода. В этих случаях можно обеспечить развертывание цикла при помощи coder.unroll. Смотрите Непостоянный индекс в varargin или varargout в цикле for.