Main Content

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

  1. In the MATLAB® Coder™ toolstrip, set Build type to MEX, Static Library, Dynamic Library, or Executable.

  2. Click Settings tab in the MATLAB Coder toolstrip.

  3. On the Memory tab, set Stack usage max to the value that you want.

Control Stack Space Usage at the Command Line

  1. To create configuration object use coder.config with arguments lib, mex, dll, or exe. For example:

    cfg = coder.config("lib");
  2. 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;

See Also

Topics