Control Stack Space Usage
You can control the maximum stack size used by your compiler or hardware. A stack is a block of memory that stores local variables for program execution. Stack memory is allocated during code generation. Stack allocation is typically more efficient for memory usage than static allocation.
The value of the configuration parameter Stack usage max is measured in bytes. Based on information from the target hardware settings and the possible execution paths in the code, the code generator estimates the stack variables that can be accommodated by this maximum. This estimate does not account for stack size changes introduced by the C/C++ compiler. Variables that do not fit in stack memory are spilled off the stack. The variables that are spilled off the stack are stored in static memory or in a spill structure if you generate reentrant code.
To control stack space usage, you can:
Increase the value of the Stack usage max parameter to raise the number of variables allocated to stack memory. If your target hardware has sufficient stack space, this reduces the amount of variables that are spilled off the stack.
Decrease the value of the Stack usage max parameter to reduce the number of variables allocated to stack memory. If your target hardware lacks sufficient stack space, this increases the number of variables that are spilled off of the stack.
Variables in recursive functions that do not fit on the stack are not stored in a
static memory or in a spill structure. Variables in recursive functions are not spilled
off the stack, even if they exceed the stack usage size. Similarly, code generation does
not account for the stack usage of custom code in calls to coder.ceval
.
Set the maximum stack usage when:
You have limited stack space, for instance, in embedded targets.
Your C/C++ compiler reports a run-time stack overflow.
Control Stack Space Usage by Using the MATLAB Coder App
In the MATLAB® Coder™ toolstrip, set Build type to MEX, Static Library, Dynamic Library, or Executable.
Click Settings tab in the MATLAB Coder toolstrip.
On the Memory tab, set Stack usage max to the value that you want.
Control Stack Space Usage at the Command Line
To create configuration object use
coder.config
with argumentslib
,mex
,dll
, orexe
. For example:cfg = coder.config("lib");
Set the property
StackUsageMax
to the value that you want.cfg.StackUsageMax=400000;
Generate Code Without Spilled Variable
If stack space is sufficient, the generated code does not require spilled variables.
Consider this MATLAB function.
function y = fooNorm(x) b = cast(x,'uint32'); y = sum(b); end
Generate C code by specifying the input argument x
as
100-by-100 matrix of doubles on a system with ample stack
space.
in = ones(100,100); cfg = coder.config('lib'); cfg.StackUsageMax = 400000; codegen fooNorm -args {in} -config cfg -report
The generated C function fooNorm
declares the variable
b_x[10000]
on the
stack.
void fooNorm(const double x[10000], double y[100]) { unsigned int b_x[10000]; ... }
void main_fooNorm(void) { double dv[10000]; double y[100]; argInit_100x100_real_T(dv); fooNorm(dv, y); }
Generate Code That Has Spilled Variables
Generate code for the same MATLAB function by using these commands with reduced value of the Stack usage max parameter.
in = ones(100,100); cfg = coder.config('lib'); cfg.StackUsageMax = 400; codegen fooNorm -args {in} -config cfg -report
The generated code defines b_x[10000]
as a static variable
because it does not fit on the
stack.
void fooNorm(const double x[10000], double y[100]) { static unsigned int b_x[10000]; ... }
void main_fooNorm(void) { static double dv[10000]; static double y[100]; argInit_100x100_real_T(dv); fooNorm(dv, y); }
Generate Reentrant Code That Has Spilled Variables
Generate
re-entrant code for the same MATLAB function fooNorm
with insufficient stack space,
using these
commands:
in = ones(100,100); cfg = coder.config('lib'); cfg.StackUsageMax = 400; cfg.MultiInstanceCode = true; codegen fooNorm -args {in} -config cfg -report
Generated C code:
void fooNorm(fooNormStackData *SD, const double x[10000], double y[100]) { int i; for (i = 0; i < 10000; i++) { double d; ... }
The input to fooNorm
is a structure
fooNormStackData
. On generating reentrant code, when
variables spill off the stack, a spill structure is generated that holds the
variables that do not fit on the
stack.
void main_fooNorm(void) { static fooNormStackData fooNormStackDataGlobal; static double dv[10000]; static double y[100]; argInit_100x100_real_T(dv); fooNorm(&fooNormStackDataGlobal, dv, y); }
The structure fooNormStackData
is defined
as:
typedef struct { unsigned int x[10000]; } b_fooNorm; typedef struct { b_fooNorm f0; } fooNormStackData;