Stack Usage Profiling From Command Line
To determine the size of stack memory that is required to run generated code, you can run software-in-the-loop (SIL) or processor-in-the-loop (PIL) simulations that generate stack usage profiles. The profiles that you generate enable you to observe the effect of compiler optimization and data input on stack usage.
This example shows how you can use line commands to produce a stack usage profile and access stack usage metrics.
Configure and Run SIL Model Programmatically
Configure a SIL simulation model that generates a workspace variable containing stack-usage measurements.
Open
SILTopModel
.openExample('ecoder/SILPILVerificationExample', ... supportingFile='SILTopModel.slx') model = bdroot;
Disable Simulink® Coverage™ and third-party code coverage analysis.
set_param(gcs,... 'CovEnable', 'off'); covSettings = get_param(gcs, 'CodeCoverageSettings'); covSettings.CoverageTool = 'None'; set_param(model, 'CodeCoverageSettings', covSettings);
Disable code execution time profiling.
set_param(model,... 'CodeExecutionProfiling', 'off'); set_param(model,... 'CodeProfilingInstrumentation', 'off');
Enable stack usage profiling.
set_param(model,... 'CodeStackProfiling', 'on');
Run the simulation.
simOut = sim(model);
stackProfile
(default) in the object
simOut
.When the simulation is complete, open the code stack profiling report.
report(simOut.stackProfile)
Access Stack Usage Metrics Programmatically
You can use line commands to access stack usage metrics contained in
stackProfile
, a coder.profile.ExecutionStack
object.
To extract stack usage metrics for tasks, run:
taskSections = simOut.stackProfile.TaskSections
taskSections = 1×2 StackTaskSection array with properties: MaximumStackUsage MaximumStackUsageTime AverageStackUsage MinimumStackUsage MinimumStackUsageTime MinimumCallDepth MinimumCallDepthTime MaximumCallDepth MaximumCallDepthTime Name NumCalls
For each task, the properties provide this information:
MaximumStackUsage
— Maximum stack usage, in bytesAverageStackUsage
— Average stack usage, in bytesMinimumStackUsage
— Minimum stack usage, in bytesMinimumCallDepth
— Minimum number of nested function callsMaximumCallDepth
— Maximum number of nested function callsName
— Name of generated taskNumCalls
— Number of times that generated task is called
The MaximumStackUsage
, AverageStackUsage
, and
MinimumStackUsage
properties indicate how much stack memory is
allocated when an instance of the task is executed (including functions called internally).
MaximumStackUsage
and MinimumStackUsage
are minimum
and maximum values for the task across the simulation. AverageStackUsage
is the mean value for the task across the simulation.
The MinimumCallDepth
and MaximumCallDepth
properties show the depth of the function-call stack. As various types of target hardware
support a limited number of nested functions, the properties help you to monitor the
possibility of saturation.
To get metrics for a specific task, for example initialize
,
run:
initializeMetrics = taskSections(1,1)
initializeMetrics = StackTaskSection with properties: MaximumStackUsage: 96 MaximumStackUsageTime: 0 AverageStackUsage: 96 MinimumStackUsage: 96 MinimumStackUsageTime: 0 MinimumCallDepth: 2 MinimumCallDepthTime: 0 MaximumCallDepth: 2 MaximumCallDepthTime: 0 Name: 'initialize' NumCalls: 1
To extract stack usage metrics for functions, run:
functionSections = simOut.stackProfile.FunctionSections
functionSections = 1×6 StackFunctionSection array with properties: Memory MaxMemory Name NumCalls
For each function, the properties provide this information:
Memory
— Stack memory used, in bytesMaxMemory
— Maximum stack memory used, in bytesName
— Name of generated functionNumCalls
— Number of times generated function is called
The Memory
property shows how much stack memory is allocated for the
function when it is called. The property does not consider functions called internally and
the property value is the same regardless of inputs passed. The MaxMemory
property considers functions called internally and its value can depend on the inputs. For
example, an internal function can be executed conditionally, depending on an argument
value.
To get metrics for a specific function, for example CounterTypeA
,
run:
counterTypeAMetrics = functionSections(1,2)
counterTypeAMetrics = StackFunctionSection with properties: Memory: 48 MaxMemory: 48 Name: 'CounterTypeA' NumCalls: 101