有没有办法可以衡量一个函数使用多少堆栈内存?
这个问题并不特定于递归函数;但我有兴趣知道递归函数会占用多少堆栈内存。
我有兴趣优化堆栈内存使用的功能;但是,如果不知道编译器已经进行了哪些优化,那么只要猜测是否正在进行真正的改进,它就是猜测。
要明确,不是关于如何优化以更好地使用堆栈的问题
那么是否有一些可靠的方法可以找出函数在C中使用了多少堆栈内存?
注意:假设它没有使用alloca
或可变长度数组,
应该可以在编译时找到它。
答案 0 :(得分:4)
这是GCC特定的(使用gcc 4.9测试):
在函数上方添加:
#pragma GCC diagnostic error "-Wframe-larger-than="
报告错误,例如:
error: the frame size of 272 bytes is larger than 1 bytes [-Werror=frame-larger-than=]
虽然方法略显奇怪,但您至少可以在编辑文件时快速执行此操作。
您可以将-fstack-usage
添加到CFLAGS,然后CFLAGS会在目标文件旁边写出文本文件。
请参阅:https://gcc.gnu.org/onlinedocs/gnat_ugn/Static-Stack-Usage-Analysis.html
虽然这非常有效,但根据您的构建系统/配置,它可能有点不方便 - 使用不同的CFLAG构建单个文件,尽管这当然可以自动化。
- (感谢@nos&#39的评论)
请注意,
似乎大多数/所有编译器自然方法依赖于猜测 - 在优化之后100%确保保持准确,所以这至少使用免费编译器给出了明确的答案。
答案 1 :(得分:1)
通过以下方式调用只有一个局部变量字的函数,可以很容易地找出占用多少堆栈空间:
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);
}
(注意:该函数声明一个只有一个字节的局部变量,但编译器通常会在堆栈上为它分配一个完整的机器字。)
因此,这将告诉您函数调用占用了多少堆栈空间。添加到函数的局部变量越多,它将占用的堆栈空间就越多。在函数内的不同作用域中定义的变量通常不会使事情复杂化,因为编译器通常会为每个局部变量在堆栈上分配一个不同的区域,而不会根据其中某些变量可能永远不会共存的事实进行优化。 / p>
答案 2 :(得分:0)
要计算当前函数的堆栈使用情况,您可以执行以下操作:
void MyFunc( void );
void *pFnBottom = (void *)MyFunc;
void *pFnTop;
unsigned int uiStackUsage;
void MyFunc( void )
{
__asm__ ( mov pFnTop, esp );
uiStackUsage = (unsigned int)(pFnTop - pFnBottom);
}