FP操作在各种x86 CPU上是否完全相同?

时间:2012-10-27 16:53:15

标签: x86 floating-accuracy

不同的x86 CPU(使用内置FPU和合理的最新版本,比如推出这个千禧年)为其浮点基元生成完全相同的结果,假设CPU上有相同的指令可用比较,相同的输入和相同的操作参数,如舍入模式?我对时间上的差异感兴趣,也不感兴趣Pentium FDIV bug(仅仅因为这个事件很古老而没有资格)。

我猜对于加法,减法,否定和舍入到整数的答案是肯定的,因为它们具有精确的定义,我很难想象实现中的差异是什么(可能是检测中的错误)溢出/下溢,但在某些应用程序中这将是一场灾难,所以我想这很久以前就已经被捕获并修复了。)

乘法似乎更可能有不同的实现:确定两个DPFPN产品的(比如说)最近可表示的双精度浮点数(64位,包括52 + 1的尾数),有时需要计算它们的乘积尾数到(大约)104位精度,对于少数LSBits来说,可以说是浪费精力。我想知道这是否尝试过,并且做得正确。或许IEEE-754或某些事实上的标准规定了什么?

分区似乎更加微妙。

而且,除了常见的设计,我怀疑所有更复杂的东西(trig函数,日志......)的实现都可以完全同步,因为可以使用各种数学方法。

我问的是纯粹的nosiness的组合;愿意提高that answer of mine;并期望一种方法(某些时候)允许在VM中运行的程序检测假装运行的CPU与真实CPU之间的不匹配。

2 个答案:

答案 0 :(得分:9)

在汇编级基本浮点指令(加,减,乘,除,平方根,FMA,舍入)总是产生相同的结果,如IEEE754标准所述。有两种指令可能会在不同的体系结构上产生不同的结果:用于计算超越运算的复杂FPU指令(FSIN,FCOS,F2XM1等),以及近似SSE指令(用于计算近似倒数的RCPSS / RCPPS,以及RSQRTSS,RSQRTPS)用于计算近似倒数平方根)。超级x87 FPU操作在微码中实现,而AFAIK除AMD K5以外的所有Intel和AMD CPU都使用相同的微码,因此您不能将其用于检测。它可能仅对检测VIA,Cyrix,Transmeta和其他旧CPU有帮助,但这些太少难以考虑。英特尔和AMD的近似SSE指令的实现方式不同,AFAIK在旧的(K8之前)和更新的AMD CPU上的实现存在一些差异。您可以使用该差异来检测AMD CPU假装为Intel,反之亦然,但这是一个有限的用例。

答案 1 :(得分:2)

除了勘误表中记载的极端情况外,所有 IA-32指令在处理器之间的行为相同。

当然,明显的例外是CPUID和MSR访问。

明显的非例外是各种逻辑,整数和浮点运算。当Maratyszczain his answer时,许多更复杂的操作都是由微码计算的。在具有不同微体系结构的处理器中,该微代码可能非常不同,但结果保证是相同的。英特尔(我没有其他x86开发人员的第一手资料)投入大量资源来确保处理器之间的向后兼容性,甚至可以复制“错误”行为(将错误更改为新规范)。

如果体系结构的行为不同,例如VMX(虚拟化)和SMM(系统管理),则控制结构包括修订ID。所有使用相同修订版ID的处理器都保证在这些体系结构方面的行为方式相同。

要回答原始问题,根据IEEE 754,FP操作,无论是x87,SSE还是AVX,都会在所有处理器上给出相同的结果。