帧指针优化的用法

时间:2014-05-07 21:30:18

标签: optimization assembly

这与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。开放第四个注册表可能会下降   出了一堆溢出代码。

我有几个问题。

  1. 溢出代码==注册溢出?
  2. 作者是否正确FPO通常被认为是痛苦的 收益不会超过收益。
  3. 今天FPO在x64架构中仍然具有相关性,因为有一个 很多寄存器都可以使用。
  4. 你使用FPO吗?什么(如果是)并且它有所作为 你呢?
  5. 最后在这篇文章中

    http://www.altdevblogaday.com/2012/05/24/x64-abi-intro-to-the-windows-x64-calling-convention/

    作者说

      

    [关注Windows x64调用约定] .....

         

    所有参数都在堆栈上保留空间,甚至是寄存器中传递的空间。实际上,有4个参数的堆栈空间   即使你的功能没有任何参数。那些参数是8   每个函数的字节数至少为32个字节   (每个函数实际上在堆栈上至少有48个字节......我会的   解释另一次)。此堆栈区域称为主页空间。   这个家庭空间背后的原因很少:

         
        
    1. 如果需要将寄存器用于其他内容,则被调用函数可以将数据存储在家庭空间中而无需移动堆栈   指针。
    2.   
    3. 它使堆栈结构易于确定。这对于调试来说非常方便,并且可能是x64的堆栈元数据所必需的(另一个   我会回到另一个时间)。 ......编译器可以使用它   无论它想要什么,优化的构建可能会很棒   使用它
    4.   

    优化的构建不会优化多余的分配吗?

2 个答案:

答案 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)我不是编译器。我的编译器不生成帧指针。

优化过量)不确定你的问题是什么。家庭区域的空间消耗不是问题。不必调整任何堆栈指针的好处是一个很大的优势,因为您需要更少的代码。对于堆栈框架之外的红色区域也是如此,这允许叶子代码使用大量内存而无需任何堆栈指针体操。