Is there a way I can measure how much stack memory a function uses?
This question isn't specific to recursive functions; however I was interested to know how much stack memory a function called recursively would take.
I was interested to optimize the function for stack memory usage; however, without knowing what optimizations the compiler is already making, it's just guess-work if this is making real improvements or not.
To be clear, this is not a question about how to optimize for better stack usage
So is there some reliable way to find out how much stack memory a function uses in C?
Note: Assuming it's not using alloca
or variable-length arrays,
it should be possible to find this at compile time.
Using warnings
This is GCC specific (tested with gcc 4.9):
Add this above the function:
#pragma GCC diagnostic error "-Wframe-larger-than="
Which reports errors such as:
error: the frame size of 272 bytes is larger than 1 bytes [-Werror=frame-larger-than=]
While a slightly odd way method, you can at least do this quickly while editing the file.
Using CFLAGS
You can add -fstack-usage
to your CFLAGS, which then writes out text files along side the object files.
See: https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html
While this works very well, its may be a little inconvenient depending on your buildsystem/configuration - to build a single file with a different CFLAG, though this can of course be automated.
– (thanks to @nos's comment)
Note,
It seems most/all of the compiler natural methods rely on guessing - which isn't 100% sure to remain accurate after optimizations, so this at least gives a definitive answer using a free compiler.
You can very easily find out how much stack space is taken by a call to a function which has just one word of local variables in the following way:
static byte* p1;
static byte* p2;
void f1()
{
byte b;
p1 = &b;
f2();
}
void f2()
{
byte b;
p2 = &b;
}
void calculate()
{
f1();
int stack_space_used = (int)(p2 - p1);
}
(Note: the function declares a local variable which is only a byte, but the compiler will generally allocate an entire machine word for it on the stack.)
So, this will tell you how much stack space is taken by a function call. The more local variables you add to a function, the more stack space it will take. Variables defined in different scopes within the function usually don't complicate things, as the compiler will generally allocate a distinct area on the stack for every local variable without any attempt to optimize based on the fact that some of these variables might never coexist.
To calculate the stack usage for the current function you can do something like this:
void MyFunc( void );
void *pFnBottom = (void *)MyFunc;
void *pFnTop;
unsigned int uiStackUsage;
void MyFunc( void )
{
__asm__ ( mov pFnTop, esp );
uiStackUsage = (unsigned int)(pFnTop - pFnBottom);
}