堆栈内存消耗如何计算?

时间:2018-09-06 16:27:18

标签: c stack embedded

我需要计算程序的堆栈内存消耗。 gcc的-fstack-usage仅计算函数的堆栈使用率,据我了解,该函数不包含其他函数调用。

void test1(){
    uint32_t stackmemory[100];
    function1();                    //needs aditional stack, say 200 Bytes
    uint32_t stackmemory2[100];
}

void test2(){
    uint32_t stackmemory[100];
    uint32_t stackmemory2[100];
    function1();                   //needs additional stack, say 200 Bytes
}

哪个test()函数使用较少的堆栈?我会说test1(),因为在function1()调用之后释放了堆栈。还是这取决于优化级别-Os / -O2 ...?

一旦输入函数,编译器是否在test1()中为其所有静态变量分配内存?还是在到达该行时分配了stackmemory2 [100]?

2 个答案:

答案 0 :(得分:1)

通常,您需要将调用图信息与-fstack-usage生成的.su文件结合起来,以查找从特定功能开始的最深堆栈使用情况。从main()或线程入口点开始,将为您提供该线程的最坏情况。

使用here中的Perl脚本,here中为您完成了创建此类工具的工作。

ARM的armcc编译器(在Keil ARM-MDK中使用)具有此功能built-in,并且可以在链接映射中包括详细的堆栈分析,包括最坏情况下的调用路径和非-警告。确定性堆栈使用情况(例如,由于递归)。

根据我观察多个编译器行为的经验,通常在函数的生存期中定义堆栈框架,而与声明的变量的生存期和范围无关。因此,在这种情况下,这两个版本不会有所不同。在没有声明它们volatile的情况下,优化程序很可能会在任何情况下都删除两个数组。但是,在这方面,您不应该依赖任何通用的观察结果-它的实现而不是语言定义。

答案 1 :(得分:-1)

  

哪个test()函数使用较少的堆栈?我会说test1()作为   调用function1()后释放堆栈。还是这取决于   优化级别-Os / -O2 ...?

它们在堆栈上分配完全相同的内存。并在同一时间:)

test1:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 800 <- on stack allocation
        mov     eax, 0
        call    function1
        nop
        leave
        ret
test2:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 800 <- on stack allocation
        mov     eax, 0
        call    function1
        nop
        leave
        ret

唯一的区别是优化启用时未使用的变量将被完全删除。

  

编译器是否在test1()中为其所有静态分配内存   变量

示例中没有任何静态变量,只有自动变量

静态变量未分配在堆栈上,因为它们在函数调用之间保持其值。

godbolt.org/z/j9-VQq