gpt4 book ai didi

我可以使用舍入来确保原子浮点运算的确定性吗?

转载 作者:太空狗 更新时间:2023-10-29 17:25:18 24 4
gpt4 key购买 nike

我正在开发需要浮点确定性的C应用程序。我还希望浮点运算相当快。这包括IEEE754未指定的标准先验功能,例如正弦和对数。与硬件浮点相比,我考虑的软件浮点实现相对较慢,因此我正在考虑简单地从每个答案中舍入一个或两个最低有效位。精度损失对我的应用程序来说是一个足够的折衷,但这是否足以确保跨平台的确定性结果?所有浮点值将为 double 。

我意识到操作顺序是浮点结果差异的另一个潜在来源。我已经有办法解决这个问题。

如果今天使用的是主要浮点硬件实现的软件实现,那就太好了,因此我可以直接检验这样的假设。

最佳答案

据我了解,您有一个先验函数(如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位“ double ”。但是Intel x86/x87可以以80位计算寄存器中的值,溢出时会四舍五入为64或32。1显示了如何更改x86/x87使用内联汇编将精度从80位控制到64位,请注意,该代码是汇编级的,而不是可移植的-但大多数其他计算机已经可以32位或64位精度进行计算,因此您无需担心x87 80位。

(顺便说一句,在x86上,您只能通过使用SSE FP来避免所有问题;旧的旧版Intel x87 FP永远无法给出完全相同的答案(尽管如果您将精度控制(PC)设置为64位而不是80位,您会得到相同的结果,除了中间出现溢出外,因为指数宽度不会受到影响,仅尾数即可))

例如。确保在所有计算机上使用相同的下溢模式。 IE。确保禁用或启用,或者相反,确保所有计算机均处于清零模式。这是Dobson的选择:冲水归零模式尚未标准化,但某些机器(例如GPU根本就没有非规范化的数字。 IE。许多机器具有IEEE标准编号FORMATS,但没有实际的IEEE标准算术(带有定理)。我的要求是要求使用IEEE denorms,但是如果我绝对偏执,我会将flush设置为零,并在软件中强制执行该操作。

(3)确保使用相同的语言ioption。较旧的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,请使用您的编译器开关。

您可能必须禁用包含sin代码的文件的所有优化。

您可能必须使用 volatile 。

希望有更具体的编译器开关。例如。对于gcc:

-ffp-contract = off ---禁用融合乘法加法,因为并非所有目标计算机都具有它们。

-fexcess precision = standard ---禁用诸如内部寄存器中的Intel x86/x87超精度之类的功能

-std = c99 ---指定相当严格的C语言标准。不幸的是,正如我今天在Google上搜索的那样,它并没有完全实现

确保您没有启用-funsafe-math和-fassociativbe-math之类的优化

关于我可以使用舍入来确保原子浮点运算的确定性吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9236022/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com