首页 > 后端开发 > C++ > 现代 C/C 编译器是否利用 Push/Pop 指令进行高效的局部变量管理?

现代 C/C 编译器是否利用 Push/Pop 指令进行高效的局部变量管理?

Barbara Streisand
发布: 2024-12-02 19:18:15
原创
651 人浏览过

Do Modern C/C   Compilers Utilize Push/Pop Instructions for Efficient Local Variable Management?

哪些 C/C 编译器可以利用 Push/Pop 指令来创建局部变量?

简介

与逐渐增加 ESP 的常见做法相反,这个问题深入探讨了使用push和pop指令建立局部变量的可能性,旨在优化代码紧凑性和可能的​​性能。

编译器注意事项

编译器优化:

  • 所有四种主要的 x86 编译器(GCC、ICC、MSVC、 clang) 已经放弃了 Push 优化。
  • 这主要是由于过去的 CPU 上 Push 的利用率很高,这对超标量核心效率产生了负面影响。
  • 但是,现代编译器重新引入了 Push /pop 可提高性能,特别是在堆栈参数和调用保留的操作方面

堆栈引擎优化:

  • 最近的 CPU,如 Intel 自 Pentium-M 以来的 CPU 和 AMD 自 Bulldozer 以来的 CPU,都采用了一个“堆栈引擎”来跟踪高效地修改 RSP。
  • 此功能可以使用 Push/pop/call/ret,而不会影响性能
  • 仔细利用推送/弹出可以通过优化速度而不仅仅是代码大小来提高性能。

代码示例

考虑以下示例:

int extfunc(int *, int *);

void foo() {
    int a=1, b=2;
    extfunc(&a, &b);
}
登录后复制

编译器输出

GCC、ICC、MSVC 和 clang 都会生成以推送指令开头的代码,然后是堆栈操作和对 ​​extfunc 的调用。这与现代编译器利用推送进行优化的观察结果一致。

最佳解决方案

进一步优化的解决方案是:

push    2                  # only 2 bytes
lea     rdi, [rsp + 4]
mov     dword ptr [rdi], 1
mov     rsi, rsp              # special case for lea rsi, [rsp + 0]
call    extfunc(int*, int*)
pop     rax                 # alternative to add rsp,8
ret
登录后复制

在这种情况下,单个入栈指令会为两个局部变量分配空间,同时使堆栈保持 16 字节对齐。这可以优化代码大小并保持效率。

其他注意事项

  • 将推送与 [rsp] 寻址模式混合可以在 Intel CPU 上引入额外的堆栈同步微指令,可能会降低效率。
  • 编译器通常不会实现这种优化,因为它需要仔细计算和平衡权衡以避免性能下降。

以上是现代 C/C 编译器是否利用 Push/Pop 指令进行高效的局部变量管理?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板