微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C 编译器忽略寄存器声明的原因

如何解决C 编译器忽略寄存器声明的原因

C 编译器忽略 register 声明的原因是什么?我知道这个声明对于现代编译器来说基本上没有意义,因为它们在适当的时候将值存储在寄存器中。我正在学习计算机体系结构课程,因此了解旧编译器为何会出现这种情况很重要。

"register 声明通知编译器中的变量 问题将被大量使用。这个想法是 register 变量 将被放置在机器寄存器中,这可能会导致更小和 更快的程序。但是编译器可以随意忽略这些建议。” ~ The C Programming Language 作者:Brian W. Kernighan 和 Dennis M. Ritchie

谢谢!

解决方法

历史上的 C 编译器可能“智能”(复杂)到一次查看一个 C 语句,例如现代的 TinyCC。或者解析整个函数以找出有多少变量,然后返回并且仍然一次只执行代码生成一个语句。有关旧编译器多么简单和幼稚的示例,请参阅 Why do C to Z80 compilers produce poor code? - 显示的一些示例可以针对特殊的简单情况进行了优化,但没有。 (尽管 Z80 和 6502 是相当糟糕的 C 编译器目标,因为(与 PDP-11 不同)“指针”不是您可以仅保留在寄存器中的东西。)

启用优化后,现代编译器确实有足够的 RAM(和编译时间)可用于使用更复杂的算法来映射整个函数的寄存器分配,并在内联之后做出正确的决定。 (例如,将程序逻辑转换为 SSA 形式。)另见 https://en.wikipedia.org/wiki/Register_allocation

register 关键字变得毫无意义;编译器已经可以注意到何时没有获取变量的地址(register 关键字不允许这样做)。或者当它可以优化地址获取并将变量保留在寄存器中时。

TL:DR:现代编译器不再需要以 register 关键字暗示的方式完全应用 as-if 规则。

他们基本上总是将所有内容保存在寄存器中,除非被迫将其溢出回内存,除非您禁用优化以实现完全一致的调试。 (因此您可以在断点处停止时使用调试器更改变量,甚至可以在语句之间跳转。)


有趣的事实:Why does clang produce inefficient asm with -O0 (for this simple floating point sum)? 展示了一个示例,其中 register float 使现代 GCC 和 clang 创建更高效​​的 asm 禁用优化

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。