这与frame pointer omitting ? Any risk?
相关但不相同我正在尝试关注这篇旧的(但仍然相关的文章)
http://blogs.msdn.com/b/larryosterman/archive/2007/03/12/fpo.aspx
拉里(作者写道)
自1995年以来,机器得到了足够快的性能 FPO实现的改进不足以应对 FPO引起的调试和分析的痛苦
然而,在页面下方的讨论中,一个用户写了
禁用FPO可能会产生严重的代码大小和性能影响。 当帧指针为时,必须禁用尾调用优化 目前,在受影响的路径中导致更大的堆栈使用。小 函数也受prolog / epilog代码的不成比例的影响。 第三,尽管仍有六个寄存器可用于帧 X86上的指针,其中只有三个是非易失性的 嵌套调用:EBX,ESI和EDI。开放第四个注册表可能会下降 出了一堆溢出代码。
我有几个问题。
最后在这篇文章中
http://www.altdevblogaday.com/2012/05/24/x64-abi-intro-to-the-windows-x64-calling-convention/
作者说
[关注Windows x64调用约定] .....
所有参数都在堆栈上保留空间,甚至是寄存器中传递的空间。实际上,有4个参数的堆栈空间 即使你的功能没有任何参数。那些参数是8 每个函数的字节数至少为32个字节 (每个函数实际上在堆栈上至少有48个字节......我会的 解释另一次)。此堆栈区域称为主页空间。 这个家庭空间背后的原因很少:
- 如果需要将寄存器用于其他内容,则被调用函数可以将数据存储在家庭空间中而无需移动堆栈 指针。
- 它使堆栈结构易于确定。这对于调试来说非常方便,并且可能是x64的堆栈元数据所必需的(另一个 我会回到另一个时间)。 ......编译器可以使用它 无论它想要什么,优化的构建可能会很棒 使用它。
醇>
优化的构建不会优化多余的分配吗?
答案 0 :(得分:1)
1.溢出代码==注册溢出?
几乎。从严格地讲,溢出代码是编译器为实现寄存器溢出而添加的代码。泄漏本身是决定将有效范围标记为无法放入寄存器。
2.作者是否正确认为FPO通常被认为是一种痛苦,而且收益并没有超过其益处。
作者可能是正确的,在现代处理器架构中,FPO将产生重要性能增益的函数类型比过去更小。然而,FPO的做使代码更小,降低了缓存压力。他们做降低了注册压力。在某些设置中,这些可能很重要。他们做通过一些指令加速prolog和epilog代码。关于调试器在没有FP的情况下工作不正常的观点值得注意。这意味着核心转储对于生产优化代码的后期验证不太有用。除了最终测试之外,你永远不想在开发过程中使用FPO。
3.今天FPO仍然与x64架构相关,因为有更多的寄存器可供使用。
现代处理器是如此多样和复杂,以至于在尝试和测量之前,你几乎不知道什么是“相关的”。
4.你使用FPO吗?什么(如果是的话)会对你产生影响吗?
我编写了一个中等大小的C库(20K SLOC),它在gcc下整体运行时间差异很小(~5%)。这是脚本语言的本地语言扩展,必须在gcc和Visual C下编译。使用它会拆分构建路径。我决定5%不值得为延长服务的目的。但如果它是一个动态流体模拟预测天气,5%可能价值数百万美元。这个决定会有所不同。
5.优化的构建不能优化多余的分配吗?
这完全取决于编译器和优化器设计器。从MS文档here看,MS已经为所有数据定义了ABI到 require 的归属空间,即使它的整个生命周期都花在了寄存器中。
答案 1 :(得分:0)
1)当您需要使用寄存器且没有任何未使用的寄存器时,您需要编写代码以在堆栈中保存一些寄存器值,然后将其恢复。
2)FPO是一个痛苦的回归,当解散主要是通过走栈。现在无论如何都存在标准的展开ABI(例如,为了启用异常处理),因此信息已经存在,并且更有效地组织(远离热代码),所以没有痛苦。当然,如果您手动编写所有机器代码会有一些痛苦,但这不是典型的用例。
3)典型的x86_64 ABI根本不使用帧指针(绝对必要时除外,比如C中的可变长度数组)。
4)我不是编译器。我的编译器不生成帧指针。
优化过量)不确定你的问题是什么。家庭区域的空间消耗不是问题。不必调整任何堆栈指针的好处是一个很大的优势,因为您需要更少的代码。对于堆栈框架之外的红色区域也是如此,这允许叶子代码使用大量内存而无需任何堆栈指针体操。