我可以使用舍入来确保原子浮点操作的确定性吗?
我正在开发一个需要浮点确定性的C应用程序。 我也希望浮点运算速度相当快。 这包括IEEE754没有规定的标准超越函数,如正弦和对数。 与硬件浮点相比,我考虑的软件浮点实现相对较慢,所以我正在考虑简单地将每个答案中的一个或两个最低有效位四舍五入。 精确度的损失对我的应用来说是一个妥协的妥协,但这足以确保跨平台的确定性结果吗? 所有浮点值都将是双精度值。
我意识到操作顺序是浮点结果变化的另一个潜在来源。 我有办法解决这个问题。
如果今天使用主要浮点硬件实现的软件实现,那将是了不起的,所以我可以直接测试这样的假设。
据我了解,你有一个像sin(x)这样的超越函数的软件实现,用IEEE标准操作(例如浮点加法和乘法)来表示,并且你希望确保你在所有机器上得到相同的答案(或者至少是你关心的所有机器)。
首先,要明白:这不适用于所有机器。 例如IBM大型机十六进制浮点不是IEEE,并且不会给出相同的答案。 为了得到确切的结果,你需要有一个IEEEE标准操作的软件实现,比如FP加法和乘法。
我猜你只关心实现IEEE标准浮点的机器。 我也猜测你并不担心NaN,因为NaN并没有被IEEE 754-1985完全标准化,并且出现了两种相反的实现:HP和MIPS,vedrsus几乎其他所有人.1
有了这些限制,如何在计算中获得可变性?
(1)如果代码正在并行化。 确保没有发生。 (这是不太可能的,但有些机器可能。)并行化是FP中结果变化的主要来源。 至少有一家我认识的关注可复制性和并行性的公司拒绝使用FP,只使用整数。
(2)确保机器安装正确。
例如,大多数机器以32位或64位精度计算(C原始标准是64位“双倍”,但是Intel x86 / x87可以在80位寄存器中计算,当溢出时为64或32。 x86 / x87精确控制从80位到64位,使用内联汇编。请注意,这个代码是汇编级别,不可移植 - 但大多数其他机器已经以32位或64位精度进行计算,并且您不必担心x87 80位。
(顺便说一句,在x86上,您只能通过使用SSE FP来避免所有问题;旧版的Intel x87 FP永远不会给出完全相同的答案(尽管如果您将精度控制(PC)设置为64位而不是80位,你将得到相同的结果,除非有中间溢出,因为指数宽度不受影响,只是尾数))
例如,确保您在所有机器上都使用相同的下溢模式。 即确保变性或启用,或者相反所有机器都处于清零模式。 这是Dobson的选择:清零模式不是标准化的,但有些机器(例如GPU)根本没有非标准化的数字。 即许多机器具有IEEE标准号码FORMATS,但不是实际的IEEE标准算术(具有denorm)。 我的druther是要求IEEE denorms,但如果我是绝对偏执狂,我会齐刷新到零,并迫使自己在软件中冲洗。
(3)确保您使用的是相同的语言选项。 较早的C程序以“double”(64位)进行所有计算,但现在允许以单精度计算。 无论如何,你想在所有机器上以同样的方式来完成。
(4)一些较小的项目用于你的代码:
避免编译器可能重新排列的大型表达式(如果它没有正确实现严格的FP开关)
可能以简单的形式写入所有的代码
double a = ...;
double b = ...;
double c = a *b;
double d = ...;
double e = a*d;
double f = c + e;
而不是
f = (a*b) + (a*c);
这可能会被优化
f = a*(b+c);
我会留下谈论最后的编译器选项,因为它更长。
如果你做所有这些事情,那么你的计算应该是绝对可重复的。 IEEE浮点是确切的 - 它总是给出相同的答案。 这是编译器在IEEE FP的引入变化的过程中重新计算的结果。
你不需要整理低位数据。 但这样做也不会受到伤害,并可能掩盖一些问题。 请记住:您可能需要为每个添加屏蔽至少一位...
(2)编译器优化在不同的机器上以不同的方式重新安排代码。 正如一位评论者所说,使用任何编译器切换为严格FP都是。
您可能必须禁用包含您的正确代码的文件的所有优化。
你可能不得不使用挥发性物质。
希望有更具体的编译器开关。 例如,对于gcc:
-ffp-contract = off ---禁用融合乘法加法,因为并非所有的目标机器都可能拥有它们。
-fexcess precision = standard ---禁用像Intel x86 / x87这样的东西在内部寄存器中过度精确
-std = c99 ---规定了相当严格的C语言标准。 不幸的是没有完全实施,因为我今天谷歌
确保你没有像-funsafe-math和-fassociativbe-math那样启用优化
链接地址: http://www.djcxy.com/p/85603.html上一篇: Can I use rounding to ensure determinism of atomic floating point operations?
下一篇: Why is FLT