c - 试图理解 gcc 选项 -fomit-frame-pointer

标签 c performance gcc cpu-registers stack-frame

我要求 Google 告诉我 gcc 选项 -fomit-frame-pointer 的含义,它将我重定向到以下语句。

-fomit-frame-pointer

Don't keep the frame pointer in a register for functions that don't need one. This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions. It also makes debugging impossible on some machines.

根据我对每个函数的了解,会在进程内存的栈中创建一个激活记录,用来保存所有的局部变量和一些更多的信息。我希望这个帧指针是一个函数的激活记录的地址。

在这种情况下,不需要将帧指针保存在寄存器中的函数类型是什么?如果我得到这些信息,我将尝试以此为基础设计新函数(如果可能的话),因为如果帧指针不保存在寄存器中,一些二进制指令将被省略。这将真正显着提高具有许多功能的应用程序的性能。

最佳答案

大多数较小的函数不需要帧指针——较大的函数可能需要一个。

这实际上是关于编译器如何设法跟踪堆栈的使用情况,以及堆栈中的位置(局部变量、传递给当前函数的参数以及为即将调用的函数准备的参数)。我认为描述需要或不需要帧指针的函数并不容易(从技术上讲,没有函数必须有帧指针——更像是“如果编译器认为有必要降低复杂性其他代码”)。

我认为您不应该将“尝试使函数没有帧指针”作为编码策略的一部分——就像我说的,简单的函数不需要它们,所以使用 -fomit-frame -pointer,您将获得一个可用于寄存器分配器的寄存器,并保存 1-3 条关于进入/退出函数的指令。如果您的函数需要帧指针,那是因为编译器认为这是比不使用帧指针更好的选择。拥有没有帧指针的函数不是目标,目标是拥有既正确又快速运行的代码。

请注意,“没有帧指针”应该会提供更好的性能,但这并不是带来巨大改进的 Elixir ——尤其是在 x86-64 上,它已经有 16 个寄存器作为起始。在 32 位 x86 上,由于它只有 8 个寄存器,其中一个是堆栈指针,占用另一个作为帧指针意味着占用了 25% 的寄存器空间。将其更改为 12.5% 是一个很大的进步。当然,为 64 位编译也会有很大帮助。

关于c - 试图理解 gcc 选项 -fomit-frame-pointer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14666665/

相关文章:

c - 为什么当我用其他任意工作使系统过载时我的程序运行得更快?

c - 如何在 GRPC++ 中获取客户端证书或更准确地说是客户端 DN?

python - 在Python中生成n个组合的最快方法

c# - 当我对一个程序进行采样分析时,它实际上运行得比不进行分析更快,这是怎么回事?

windows - C(++) 编译器转换 - 请让 DJGPP 消失

compilation - GCC 预处理器输出中的调试信息

不能在幂函数中使用常数

arrays - 函数中 str[strlen(src)+1] 和 char *str=(char*)malloc((strlen(src)+1)*sizeof(char)) 的区别

java - Integer.parseInt(scanner.nextLine()) 与 scanner.nextInt()

c - 从内存中读取 Big Endian 并增加内存