是否有优化浮点运算精度(相对速度)的编译器?
-
20-09-2019 - |
题
我们知道,编译器是优化我们的代码越来越好,并使其运行速度更快,但我的问题是,有可以优化浮点操作,以确保更高的精确度的编译器。
例如一个基本规则是除了之前执行乘法,这是因为乘法和除法使用浮点数不会引入不准确性一样大,该加法和减法的,但可以增加通过加法和减法引入的误差的大小,所以应该在许多情况下首先进行。
因此,像浮点运算
y = x*(a + b); // faster but less accurate
应改为
y = x*a + x*b; // slower but more accurate
是否有将改进的浮点精确度在速度为代价等我上面表明优化任何编译器?或者是编译器的主要关注点与出速度看浮点运算的准确性?
由于
更新:选择的答案,表现出了非常好的例子这种类型的优化是行不通的,所以它不可能让编译器事先知道什么是计算y的更准确的方法。感谢您的反例。
解决方案
您前提是有故障的。 x*(a + b)
,是(通常)不超过x*a + x*b
不太准确。事实上,它往往会更精确,因为它仅执行两个浮点操作(且因此招致只有两个舍入误差),而后者执行三个操作。
如果你知道一些关于值的x
,a
预期的分布,b
先验的,那么你就可以做出明智的决定,但是编译器几乎从来没有获得这类信息。
这一边,如果有什么写程序的人实际上的意味着的x*(a+b)
特别的希望的由操作的特定序列引起正好倒圆?这样的事情实际上是相当常见的高品质的数值算法。
更好做程序员写的,而不是你认为他可能打算。
修改 - 强>一个例子来说明,其中变换你建议在精度的灾难性损失结果的情况:假设
x = 3.1415926535897931
a = 1.0e15
b = -(1.0e15 - 1.0)
然后,在double
评估我们得到:
x*(a + b) = 3.1415926535897931
但
x*a + x*b = 3.0
其他提示
编译器通常为“优化”的准确性的过速,定义为精确实现IEEE 754标准的精度。而整数运算可以在不造成溢出任何方式重新排序,FP操作需要为程序员指定要准确执行。这可能会牺牲数值精度(普通C编译器都没有配备来优化该),但忠实地实现了程序员问。
一个程序员谁是肯定他还没有手动精确度可以使编译器的功能,如GCC的-funsafe-math-optimizations
和-ffinite-math-only
到可能提取额外的速度进行了优化。但通常没有太多增益。
没有,没有。斯蒂芬佳能给出了一些很好的理由,这将是一个愚蠢的想法,他是正确的;所以你不会找到一个编译器,做到这一点。
如果你作为程序员有关于你操作,您可以使用括号,临时变量和类似的构造强烈地暗示你想怎么把事情做完的编译器。数字的范围有一定的了解。