6

我的目标是在可能具有不同 CPU 架构和操作系统的不同机器上运行需要非整数的模拟。主要优先级是给定相同的初始状态,每台机器都应该完全相同地再现模拟。次要优先级是我希望计算的性能和精度尽可能接近双精度浮点数。

据我所知,似乎没有任何方法可以从 Haskell 程序中影响浮点计算的确定性,类似于 C 中的_controlfpand_FPU_SETCW宏。所以,目前我认为我的选择是

  1. 使用数据.比率
  2. 使用数据。固定
  3. 使用定点包中的Data.Fixed.Binary
  4. 编写一个模块以_ controlfp通过 FFI 调用(或每个平台的等效模块)。
  5. 可能,还有别的?

定点算术库的一个问题是它们没有为它们定义例如三角函数或对数(因为它们没有实现Floating类型类)所以我想我需要为所有函数提供查找表模拟种子数据。或者有什么更好的方法吗?

两个定点库也隐藏了newtype构造函数,因此据我所知,任何(反)序列化都需要通过toRational/来完成fromRational,这感觉会增加不必要的开销。

我的下一步是对不同的定点解决方案进行基准测试,以了解真实世界的性能,但与此同时,我很乐意听取您对此主题的任何建议。

4

1 回答 1

7

IEEE 754-2008 标准的第 11 条描述了可重现的浮点结果所需的内容。除其他外,您需要明确的表达式评估规则。一些语言允许以额外的精度计算浮点表达式或允许对表达式进行一些更改(例如a*b+c在单个指令中计算而不是单独的乘法和加法指令)。我不知道 Haskell 的语义。如果 Haskell 没有将表达式精确地映射到明确的浮点运算,那么它就不能支持可重现的浮点结果。

此外,由于您提到三角函数和对数函数,请注意这些函数因实现而异。我不知道有任何数学库提供每个标准数学函数的正确舍入实现。(CRLibm是一个创建项目。)所以每个数学库都使用自己的近似值,它们的结果略有不同。也许您可以通过在您的模拟代码中包含一个数学库来解决这个问题,以便使用它来代替每个 Haskell 实现的默认库。

在二进制浮点数和十进制数字之间转换的例程也是实现之间差异的一个来源。这不像过去那样成为问题,因为正确转换的算法是已知的。但是,这可能需要在每个实现中进行检查。

于 2013-05-14T13:26:31.850 回答