Разверните for
- цикл путем создания копии тела цикла для каждой итерации цикла
coder.unroll()
coder.unroll(flag)
coder.unroll()
разворачивает for
- цикл. Вызов coder.unroll
должен быть на строке отдельно сразу предшествованием for
- цикл, который это разворачивает.
Вместо того, чтобы произвести for
- цикл в сгенерированном коде, развертывание цикла производит копию for
- тело цикла для каждой итерации цикла. В каждой итерации индекс цикла становится постоянным. Чтобы развернуть цикл, генератор кода должен смочь определить границы цикла for-
.
Для маленьких, жестких циклов разворачивание может улучшить производительность. Однако для больших циклов, разворачивание может значительно увеличить время генерации кода и сгенерировать неэффективный код.
coder.unroll
проигнорирован за пределами генерации кода.
разворачивает coder.unroll(flag)
for
- цикл, если flag
является true
. flag
оценен во время генерации кода. Вызов coder.unroll
должен быть на строке отдельно сразу предшествованием for
- цикл, который это разворачивает.
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.