c - 我什么时候应该省略帧指针?

标签 c optimization compiler-construction

省略帧指针时有没有实质性的优化? 如果我通过阅读理解正确 this page, -fomit-frame-pointer 当我们想避免保存、设置和恢复帧指针时使用。

这是否仅针对每个函数调用完成?如果是,是否真的值得为每个函数避免一些指令? 优化不是微不足道的吗? 除了调试限制之外,使用此选项的实际含义是什么?

我在使用和不使用这个选项的情况下编译了以下 C 代码

int main(void)
{
        int i;

        i = myf(1, 2);
}

int myf(int a, int b)
{
        return a + b;
}

,

# gcc -S -fomit-frame-pointer code.c -o withoutfp.s
# gcc -S code.c -o withfp.s

.

diff -u 分析这两个文件显示了以下汇编代码:


--- withfp.s    2009-12-22 00:03:59.000000000 +0000
+++ withoutfp.s 2009-12-22 00:04:17.000000000 +0000
@@ -7,17 +7,14 @@
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
-       pushl   %ebp
-       movl    %esp, %ebp
        pushl   %ecx
-       subl    $36, %esp
+       subl    $24, %esp
        movl    $2, 4(%esp)
        movl    $1, (%esp)
        call    myf
-       movl    %eax, -8(%ebp)
-       addl    $36, %esp
+       movl    %eax, 20(%esp)
+       addl    $24, %esp
        popl    %ecx
-       popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
@@ -25,11 +22,8 @@
 .globl myf
        .type   myf, @function
 myf:
-       pushl   %ebp
-       movl    %esp, %ebp
-       movl    12(%ebp), %eax
-       addl    8(%ebp), %eax
-       popl    %ebp
+       movl    8(%esp), %eax
+       addl    4(%esp), %eax
        ret
        .size   myf, .-myf
        .ident  "GCC: (GNU) 4.2.1 20070719 

有人可以阐明上面代码中 -fomit-frame-pointer 确实产生影响的关键点吗?

编辑 objdump 的输出替换为 gcc -S

最佳答案

-fomit-frame-pointer 允许一个额外的寄存器可用于通用用途。我认为这在 32 位 x86 上真的只是一个大问题,它有点缺乏寄存器。*

人们希望看到 EBP 不再在每次函数调用时保存和调整,并且可能在正常代码中额外使用 EBP,并且在 EBP 用作通用寄存器的情况下堆栈操作更少。

您的代码太简单了,无法从这种优化中看到任何好处——您没有使用足够的寄存器。此外,您还没有打开优化器,这可能是查看其中一些效果所必需的。

* ISA 寄存器,不是微架构寄存器。

关于c - 我什么时候应该省略帧指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1942801/

相关文章:

c - 什么是 LPTHREAD_START_ROUTINE?

c - 任务的 UML 表示

Java 递归优化

image - Google PageSpeed Insights 优化运行新图像压缩的图像?

Java编译器自动重命名参数(混淆)

assembly - 中间语言的最小汇编指令集?

c - sprintf 的一件有趣的事

c - 在字符指针数组中打印元素时未确定的行为?

javascript - 禁用 r.js 中的丑陋行为

c - 如何基于 C 代码创建转换图