Unroll for
-loop by making a copy of
the loop body for each loop iteration
coder.unroll()
unrolls a for
-loop.
The coder.unroll
call must be on a line by itself
immediately preceding the for
-loop that it unrolls.
Instead of producing a for
-loop in the
generated code, loop unrolling produces a copy of the for
-loop
body for each loop iteration. In each iteration, the loop index becomes
constant. To unroll a loop, the code generator must be able to determine
the bounds of the for-
loop.
For small, tight loops, unrolling can improve performance. However, for large loops, unrolling can increase code generation time significantly and generate inefficient code.
coder.unroll
is ignored outside of code
generation.
for
-loop To produce copies of a for
-loop
body in the generated code, use coder.unroll
.
In one file, write the entry-point function call_getrand
and
a local function getrand
. getrand
unrolls
a for
-loop that assigns random numbers to an n-by-1
array. call_getrand
calls getrand
with
the value 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
Generate a static library.
codegen -config:lib call_getrand -report
In the generated code, the code generator produces a copy
of the for
-loop body for each of the three loop
iterations.
static void getrand(double y[3]) { y[0] = b_rand(); y[1] = b_rand(); y[2] = b_rand(); }
for
-loop Unrolling with FlagControl loop unrolling by using coder.unroll
with
the flag
argument.
In one file, write the entry-point function call_getrand_unrollflag
and
a local function getrand_unrollflag
. When the
number of loop iterations is less than 10, getrand_unrollflag
unrolls
the for
-loop. call_getrand
calls getrand
with
the value 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
Generate a static library.
codegen -config:lib call_getrand_unrollflag -report
The number of iterations is not less than 10. Therefore, the
code generator does not unroll the for
-loop. It
produces a for
-loop in the generated code.
static void getrand_unrollflag(double y[50]) { int i; for (i = 0; i < 50; i++) { y[i] = b_rand(); } }
for
-Loopfunction 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
-Loop Unrollingfunction 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
Sometimes, the code generator unrolls a for
-loop even
though you do not use coder.unroll
. For example, if a
for
-loop indexes into a heterogeneous cell array or into
varargin
or varargout
, the code
generator unrolls the loop. By unrolling the loop, the code generator can
determine the value of the index for each loop iteration. The code generator
uses heuristics to determine when to unroll a for
-loop. If
the heuristics fail to identify that unrolling is warranted, or if the number of
loop iterations exceeds a limit, code generation fails. In these cases, you can
force loop unrolling by using coder.unroll
. See Nonconstant Index into varargin or varargout in a for-Loop.