如何测量C中的函数堆栈使用?

时间:2015-02-12 21:54:32

标签: c stack-memory

有没有办法可以衡量一个函数使用多少堆栈内存?

这个问题并不特定于递归函数;但我有兴趣知道递归函数会占用多少堆栈内存。

我有兴趣优化堆栈内存使用的功能;但是,如果不知道编译器已经进行了哪些优化,那么只要猜测是否正在进行真正的改进,它就是猜测。

要明确,是关于如何优化以更好地使用堆栈的问题

那么是否有一些可靠的方法可以找出函数在C中使用了多少堆栈内存?


注意:假设它没有使用alloca可变长度数组, 应该可以在编译时找到它。

3 个答案:

答案 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=]

虽然方法略显奇怪,但您至少可以在编辑文件时快速执行此操作。

使用CFLAGS

您可以将-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);
}