Clang 与 1 优化的倒数

Clang reciprocal to 1 optimisations

经过与同事的讨论,我最终测试了 clang 是否会优化两个除法(倒数为 1)到一个除法。

const float x = a / b; //x not used elsewhere const float y = 1 / x;

如果 x 仅用作临时步长值,理论上 clang 可以优化为 const float y = b / a,不是吗?

这是一个简单测试用例的输入和输出:https://gist.github.com/Jiboo/d6e839084841d39e5ab6(在两个输出中你可以看到它执行了两个除法,而不是优化)

这个相关问题在我的理解背后,似乎只关注为什么不使用特定指令,而在我的情况下,它是未完成的优化:

谢谢, JB.

不,clang 不能那样做。

但首先,您为什么要使用浮动? float 有六位精度,double 有 15 位。除非你有充分的理由,你可以解释,使用 double。

1 / (a / b) 在浮点运算中与 b / a 不同。编译器必须做的是第一种情况:

  1. a 除以 b
  2. 将结果舍入到最接近的浮点数
  3. 结果除以 1
  4. 将结果舍入到最接近的浮点数。

第二种情况:

  1. 将 b 除以 a。
  2. 将结果舍入到最接近的浮点数。

编译器只能在保证结果相同的情况下更改代码,如果编译器编写者无法提供结果相同的数学证明,则编译器无法更改代码。第一种情况有两次舍入操作,对不同的数进行舍入,所以不太可能保证结果相同。

编译器不像数学家那样思考。在您认为简化表达式在数学上微不足道的地方,编译器还有很多其他事情需要考虑。实际上,编译器很可能比程序员聪明得多,而且对 C 标准的了解也多得多。

优化编译器的 "mind":

可能就是这样的事情
  • 啊,他们写了 a / b 但只在一个地方使用 x,所以我们不必在堆栈上分配那个变量。我将删除它并使用 CPU 寄存器。
  • 嗯,整数文字 1 除以浮点变量。好的,我们必须先在这里调用平衡,然后将该文字转换为浮点数 1.0f.
  • 程序员指望我生成的代码包含将 1.0f 除以另一个浮点变量所涉及的潜在浮点不准确!所以我不能只用 b / a 交换这个表达式,因为那样的话程序员似乎想要的浮点不准确就会丢失。

等等。有 很多 的注意事项。您最终得到的机器代码很难提前预测。只知道编译器会严格按照您的说明进行操作。