是否有编译器优化浮点运算以获得准确性(而不是速度)?

hha*_*fez 5 compiler-construction floating-point optimization floating-accuracy

我们知道编译器在优化代码方面越来越好,并使其运行得更快,但我的问题是编译器可以优化浮点运算以确保更高的准确性.

例如,一个基本规则是在加法之前执行乘法,这是因为使用浮点数的乘法和除法不会引入与加法和减法一样大的不准确性,但会增加加法和减法引入的不准确性的大小,所以它应该在许多情况下首先完成.

所以一个浮点运算就像

y = x*(a + b); // faster but less accurate
Run Code Online (Sandbox Code Playgroud)

应该改为

y = x*a + x*b; // slower but more accurate
Run Code Online (Sandbox Code Playgroud)

是否有任何编译器会以牺牲速度为代价优化浮点精度,如上所示?或者编译器主要关注的是如何快速查看浮点运算的准确性?

谢谢

更新:选择的答案,显示了一个非常好的例子,这种类型的优化不起作用,因此编译器不可能事先知道评估y的更准确的方法.谢谢你的反例.

Ste*_*non 10

你的前提是错误的. x*(a + b),(一般情况下)准确度不低于x*a + x*b.事实上,它通常会更准确,因为它只执行两个浮点运算(因此只产生两个舍入误差),而后者执行三个运算.

如果你知道一些关于值的预期分布x,ab先验的,那么你可以作出明智的决定,但是编译器几乎从来没有获得这类信息.

除此之外,如果编写程序的人实际意味着 x*(a+b)并且特别想要由特定操作序列引起的精确舍入,该怎么办?在高质量的数值算法中,这种事实上很常见.

最好是做程序员写的,而不是你认为他可能想要的.

编辑 -一个例子来说明你建议的转换导致灾难性的精度损失的情况:假设

x = 3.1415926535897931
a = 1.0e15
b = -(1.0e15 - 1.0)
Run Code Online (Sandbox Code Playgroud)

然后,评估double我们得到:

x*(a + b) = 3.1415926535897931
Run Code Online (Sandbox Code Playgroud)

x*a + x*b = 3.0
Run Code Online (Sandbox Code Playgroud)

  • 浮点乘法永远不会导致舍入的说法显然是错误的. (4认同)