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 setting StackUsageMax is measured in bytes. Based on information from the target hardware settings and the possible execution paths in the code, the software estimates the stack variables that a certain value of StackUsageMax can accommodate. This estimate does not account for stack size changes introduced by the 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 a spill structure if you are trying to generate reentrant code.

  • You can increase StackUsageMax 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.

  • You can decrease StackUsageMax 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 couldn't fit on the stack are not stored in a static memory, or in a spill structure if you generate reentrant code. 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.

This example shows how to set the maximum stack space that the generated code uses. Set the maximum stack usage when:

  • You have limited stack space, for instance, in embedded targets.

  • Your C compiler reports a run-time stack overflow.

Control Stack Space Usage by Using the MATLAB Coder App

  1. To open the Generate dialog box, on the Generate Code page, click the Generate arrow .

  2. Set Build type to Source Code, MEX, Static Library, Dynamic Library, or Executable (depending on your requirements).

  3. Click More Settings.

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

Control Stack Space Usage at the Command Line

  1. Create a configuration object for code generation.

    Use coder.config with arguments 'lib', mex,'dll', or 'exe' (depending on your requirements). For example:

    cfg = coder.config('lib');
  2. Set the property StackUsageMax to the value that you want.

    cfg.StackUsageMax=400000;

Generated Code Without Spilled Variables

The various outcomes depend on the amount of stack space.

On generating code for the following MATLAB® code with ample stack space, the generated code is:

function y = fooNorm(x)
b = cast(x,'uint32');
y = sum(b);
end

The input to the function fooNorm(x) is a 100-by-100 matrix of ones.

void fooNorm(const double x[10000], double y[100])
{
  double d;
  unsigned int b[10000];
  ...
}
static void main_fooNorm(void)
{
  double dv[10000];
  double y[100];
  argInit_100x100_real_T(dv);
  fooNorm(dv, y);
}
This code snippet highlights the entry-point function fooNorm. The function main_fooNorm declares the variable dv[10000] and y[100]on the stack, which is the input to the function fooNorm.

Generated Code That Has Spilled Variables

When you generate code for the same MATLAB code with insufficient stack space, the code is:

void fooNorm(const double x[10000], double y[100])
{
  static unsigned int b[10000];
  double d;
  ...
}
static void main_fooNorm(void)
{
  static double dv[10000];
  static double y[100];
  argInit_100x100_real_T(dv);
  fooNorm(dv, y);
}
The variables b[10000], dv[10000], and y[100] are declared as static variables because they do not fit on the stack.

Generated Reentrant Code That Has Spilled Variables

When you generate reentrant code for the same MATLAB code with insufficient stack space, the generated code is:

void fooNorm(fooNormStackData *SD, const double x[10000], double y[100])
{
  double d;
  ...
}
static void main_fooNorm(void)
{
  static double dv[10000];
  static double y[100];
  argInit_100x100_real_T(dv);
  fooNorm(&fooNormStackDataGlobal, dv, y);
}
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.

The structure fooNormStackData is defined as:

typedef struct {
  struct {
    unsigned int b[10000];
  } f0;
} fooNormStackData;

Related Topics