现实世界中有没有不使用IEEE 754的CPU?

42
我正在优化一个基于数值/统计库的排序函数,假设在过滤掉任何NaN并进行一些处理后,浮点数可以作为32位整数进行比较而不改变结果,双精度浮点数可以作为64位整数进行比较。
这似乎可以将这些数组的排序速度提高约40%,只要浮点数的位级表示是IEEE 754。是否有人们实际使用(不包括此库不针对的嵌入式设备)使用其他表示法的真实CPU可能会破坏这个假设?
参考:

非常有趣 - 你能详细说明一下你是如何将它们作为整数进行比较的吗? - Saideira
4
请注意,您可能也假定整数字节序和浮点数字节序相同,这在大多数(所有?)“正常”的 CPU 上是正确的,但在符合IEEE754标准的机器上理论上可能会有所不同。 - Peter Cordes
5个回答

27
除了有缺陷的Pentium之外,任何基于x86或x64的CPU都使用IEEE 754作为它们的浮点算术标准。
以下是FPA标准及其采用情况的简要概述。
IEEE 754:       Intel x86, and all RISC systems (IBM Power
                and PowerPC, Compaq/DEC Alpha, HP PA-RISC,
                Motorola 68xxx and 88xxx, SGI (MIPS) R-xxxx,
                Sun SPARC, and others);

VAX:            Compaq/DEC

IBM S/390:      IBM (however, in 1998, IBM added an IEEE 754
                option to S/390)

Cray:           X-MP, Y-MP, C-90; other Cray models have been
                based on Alpha and SPARC processors with
                IEEE-754 arithmetic.

除非您计划在相当奇特的CPU体系结构上支持您的库,否则可以安全地假设目前99%的CPU都符合IEEE 754标准。


24
有所不同。你列出的架构在许多实际应用中几乎支持IEEE754,但有一些要点,比如没有完整的NaN集,将denorms强制为零,在乘法/除法结果中存在一两个ULP的误差,根据操作数顺序不同,乘法可能会相差一两个ULP等。因此,“99%的CPU符合IEEE754标准”需要一个免责声明-从某种意义上说是正确的,对于问题的目的来说是正确的,但通常细节中经常隐藏着魔鬼。更确切地说,99%的CPU符合99%的IEEE754标准。 - moonshadow
2
外来的架构标准委员会关心的事项 - phuclv
2
@phuclv:完全支持IEEE-754语义的架构并不是非常奇异。即使在现代CPU上,必须处理所有可能的无穷大、NaN和denormal情况的代码通常比可以通过稍微改变这些行为进行优化的代码慢得多。 - supercat
@moonshadow:就精确提出的问题而言,那些flush-to-zero和缺乏精度并不重要。浮点/双精度在内存中的格式仍然是IEEE754二进制32和二进制64,因此可以使用整数比较(只要它们都是正数,或者符号位得到适当处理)。还假设浮点字节序=整数字节序,这个答案没有涉及到。 - Peter Cordes

15

这取决于你将“现实世界”和想象中的世界之间划定的界限。

  1. Vax G格式仍然在Alpha计算机上得到支持(HP表示他们将至少支持到2013年)。
  2. IBM十六进制FP仍然得到IBM z系列主机的支持。他们增加了IEEE二进制和十进制的支持,但据我所知,它们很少被使用,因为十六进制FP要快得多(IBM已经对其进行了约45年的优化...)

直到最近,Unisys仍在销售支持Burroughs FP格式的ClearPath IX服务器,以及支持Univac FP格式的ClearPath MCP机器。我相信现在它们只能在仿真器(Xeons)上运行,但从软件视角来看,它们可能会继续活跃使用十年甚至更长时间。

甚至还有少数人在使用DtCyber在(模拟的)Control Data主机上运行Plato,具有其独特的浮点格式。(抱歉,但我的第一个严肃编程是在CDC Cyber机器上进行的,所以我不能抵制提到它,即使它已经几十年没有成为“现实世界”)。


7

Cell处理器的SPU在一些方面有所不同(例如缺少INF和NAN),但我认为这些差异不会破坏您的假设......


6
好的。ARM-Neon SIMD单元(用于新版iPhone和其他移动设备中)在几个方面有所不同。虽然,CPU能够在VPF模式下执行符合标准的浮点计算。哦,此外,MIPS R5900(PlayStation 2)也存在一些问题。最明显的是乘法的最后一位尾数未定义。 - Nils Pipenbrinck
5
我目前在工作桌上有三个嵌入式硬件设备,它们分别使用了三种不同的基于PowerPC的CPU,但这些CPU都存在各自不同的不符合标准的问题... - moonshadow

5

PowerPC处理器(Mac电脑在2006-2007年左右之前及众多现有的IBM服务器)使用由两个双精度浮点数组成的128位格式作为长双精度,而不是IEEE 754扩展格式。

然而,在C或Objective-C中,没有一种便携式的方法将32位或64位浮点数解释为整数(假设float和uint32_t或double和uint64_t具有相同数量的位)。当我需要执行这种操作时,我必须根据编译器编写不同的代码(其中一个使用union,另一个通过将double*强制转换为long long*)。不知道在C++中是否可以通过reinterpretcast以便携方式实现。


这是双倍精度算术(double-double arithmetic)的内容。 - phuclv
2
1980年代的Macintosh“标准苹果数值环境”使用32、64和80位浮点类型,其中80位类型最快,因为指数和尾数可以轻松加载到寄存器中而无需进行位掩码,并且虽然我不知道SANE是否利用了这一事实,但延迟归一化可以避免重复浮点加法中有时会出现的最慢部分。 - supercat

1
许多实际的CPU没有任何本地浮点格式。对于这些CPU,C和其他语言的许多实现都会捆绑使用IEEE-754单精度和双精度格式的库,并省略扩展精度格式,尽管其他格式在许多情况下更适合。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接