主要内容

Memory Use

Measures stack memory usage of various callable entities of your code

Since R2023b

Description

This metric measures the stack memory consumed by the functions and other callable entities of your code.

Polyspace Implementation

When you calculate memory use, Polyspace® Test™ instruments your source code to calculate the number of calls to functions and stack memory consumption. Polyspace Test assumes that the stack memory required by a function is allocated during function entry. This assumption might not be true in cases where the stack memory is allocated at run time, such as when you use variable length arrays. Polyspace Test calculates the stack consumption of a called function by subtracting the position of the stack pointer during a function entry from the last known position of the stack pointer.

When calculating the stack memory required by a function, Polyspace Test calculates several different metrics:

  • Self — The amount of stack memory required by a function. Consider a function foo(). Assume that the position of the stack pointer is initially at SP0. When foo() is called, the stack pointer moves to SP1. Then, Polyspace Test calculates the Self value as:

    Self = SP1-SP0 

  • Max — The maximum amount of stack memory required by a function. A function might require different amounts of stack memory along different execution paths. The Max value represents the maximum possible stack memory consumed by the different execution paths.

  • Count — Represents the number of times a function executes. If the count value of a function exceeds UINT_MAX, Polyspace sets the count value to UINT_MAX.

Polyspace Test does not support calculating more than one of the code coverage, execution time, or memory use metrics at a time.

Examples

expand all

In this example, you calculate the stack memory use of your code. For details, see Calculate Execution Time and Memory Use of C/C++ Code.

Save this source in a writable folder SRC.

 long long power(double x, int n){
	 long long BN = 1;
	 for(int i = 0; i<n;++i){
		 BN*=x;
	 }
	 return BN;
 }
 
 double AppxIndex(double m, double f){
	 double U = (power(m,2) - 1)/(power(m,2)+2);
	 double V = (power(m,4) + 27*power(m,2)+38)/(2*power(m,2)+3);
	 return (1+2*f*power(U,2)*(1+power(m,2)*U*V + power(m,3)/
         power(m,3)*(U-V)))/( (1-2*f*power(U,2)*(1+power(m,2)*U*V 
        + power(m,3)/power(m,3)*(U-V))));
 }
 
 int main(){
 AppxIndex(1.5, 1.1);
 return 1;
 }

Instrument the source code for memory use. At the command line enter:

polyspace-code-profiler -instrument -limit-instrumentation-to  SRC -instrum-dir  instrumFolder -stack-metric-level detailed -prof-counter-size 64 -- gcc  SRC/source.c TEST_SOURCE -I TEST_INCLUDE

Here, TEST_SOURCE is polyspaceroot/polyspace/pstest/pstunit/src/pstunit.c and TEST_INCLUDE is polyspaceroot/polyspace/pstest/pstunit/include. The path is the same for both Linux® and Windows® systems.

Produce the test executable by linking the instrumented source code and the Polyspace Test run-time library:

g++ -o source.0 pstunit.o PSLIB
Here, PSLIB is the path to the run-time library appropriate for your environment.

Run the test executable to gather memory use data:

polyspace-code-profiler -run -instrum-dir $instrumFolder -results-dir runFolder -- Executable
Here, Executable is the test executable you generated in the previous step.

Create the report:

polyspace-code-profiler -report -html -report-dir Report  runFolder/output_run.psprof

Polyspace Test stores the HTML report in the Report folder. The results indicate that the function AppxIndex() uses the most stack memory among the functions in your code.

Tips

  • When reviewing stack profiling results, note that the reported memory use represents an upper limit of stack usage for your code. This is because the instrumentation process for stack profiling injects various macros into copies of your source code, which may create additional local objects and alter stack memory usage.

  • C and C++ source code is instrumented differently in order to accommodate the features of C++ that are absent in C. The calculated memory use of the same source code might increase slightly if you compile the code using a C++ compiler.

  • The memory use per function is calculated at function startup. If a function allocates some memory after startup, that part of the memory use might be reported on a child function (callee).

    For instance, the function PIController_Update_wrapper() works with a variable-length array integral_state. The memory for the array is allocated after function startup and is therefore reported as memory use of the child function PIController_Update().

    void PIController_Update_wrapper(
          const int N
    ) {
          float integral_state[N];
          for(i=0;i<N;i++)
          {
              integral_state[i] = i;
          }
          PIController_Update(integral_state, N);
    }
    

Version History

Introduced in R2023b