【问题标题】:Fixing Register Spilling in Your Program修复程序中的寄存器溢出
【发布时间】:2023-02-24 03:19:20
【问题描述】:

我通过 CLANG 的优化报告看到我的热循环在regalloc pass 中有寄存器溢出。是否有任何关于如何避免溢出的通用编程技术,或者如何建议编译器更喜欢溢出的变量。我在网上找,但找不到任何东西。

【问题讨论】:

    标签: performance optimization compiler-construction cpu-registers register-spilling


    【解决方案1】:

    在 C 和 C++ 中,register关键字专门为此设计:

    register:自动存储时长。还提示编译器将对象放入处理器的寄存器中。

    话虽这么说,但自 C++17 以来,它现在已过时且未使用(尽管仍在 C 中使用)。 Here 是关于 C 语言的文档,here 是关于 C++ 的文档。

    AFAIK,现代编译器倾向于简单地忽略这个关键字,因为它们往往做得非常好。即使它们失败了,在具有 16 个通用寄存器和通常至少 2 个加载单元(最近的处理器也往往有两个存储单元)的现代 x64 主流处理器上,寄存器溢出也不是那么严重。也就是说,对于嵌入式处理器和一些非常关键的循环来说,这仍然是一个问题。

    一种解决方案是简单地避免在关键循环中使用许多变量并尽可能缩小它们的范围(尽管优化编译器现在应该能够很好地重新排序指令)。出于这个原因,它有时可以有益于将循环拆分为两个或多个从而减轻套准压力。这种方法在现代处理器上特别有用,由于指令级并行性和乱序执行,基本循环的开销相对较小。执行寄存器分块优化时,必须针对目标架构仔细调整分块大小,以避免实际上完全破坏优化的寄存器溢出。在一些绝望的情况下或在非常关键的循环中,一个解决方案就是直接用汇编写代码. AFAIK,一些像 Openh264(快速视频解码)GOTO BLAS(快速基本线性代数)这样的项目就是这样做的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      • 2020-02-01
      • 1970-01-01
      相关资源
      最近更新 更多