Haskell的有限差异,或如何禁用潜在优化
||
我想实现以下朴素(一阶)有限差分函数:
finite_difference :: Fractional a => a -> (a -> a) -> a -> a
finite_difference h f x = ((f $ x + h) - (f x)) / h
如您所知,存在一个微妙的问题:必须确保(x + h)
和x
相差一个可精确表示的数字。否则,结果会产生巨大的错误,这是因为(f $ x + h) - (f x)
具有灾难性的抵消作用(并且必须仔细选择h
,但这不是我的问题)。
在C或C ++中,可以这样解决问题:
volatile double temp = x + h;
h = temp - x;
而volatile
修饰符将禁用与变量temp
有关的任何优化,因此我们可以确保\“聪明\”编译器不会优化掉这两行。
我对Haskell的了解还不够,不知道如何解决此问题。恐怕
let temp = x + h
hh = temp - x
in ((f $ x + hh) - (f x)) / h
Haskell(或它使用的后端)将对其进行优化。在这里,我如何得到等价的6英镑(如果可能的话,不牺牲懒惰)?我不介意GHC的具体答案。
没有找到相关结果
已邀请:
3 个回复
妒垮
这将起作用,但会带来很小的成本。 第二种解决方案:使用volatile在C语言中编写规范化函数,然后通过FFI对其进行调用。性能损失将是最小的。 现在提出建议:当前数学尚未优化,因此目前可以正常使用。您担心它会在将来的编译器中损坏。我认为这不太可能,但也不太可能使我也不想对此加以防范。因此,编写一些涵盖相关案例的单元测试。然后,如果将来确实发生故障(出于任何原因),您将确切知道原因。
抬澈帅沮
(最有可能触发某些优化的情况):
编译为:
并且类似地(甚至更少的重写)用于多态版本。 因此,当内联变量时,并没有优化数学。 除了看核心之外,我想不出一种保证所需属性的方法。
郡豪靠暖
将得到优化。只是一个猜测。