10

假设相同的指令在被比较的 CPU 上可用,相同的输入和相同的操作参数,例如舍入模式?我对时间上的差异不感兴趣,对Pentium FDIV 错误也不感兴趣(仅因为该事件是古老的,所以不符合条件)。

我想对于加法、减法、否定和四舍五入来说答案是肯定的,因为它们有精确的定义,而且我几乎无法想象实现中的差异可能是什么(可能缺少检测溢出的错误/下溢,但这在某些应用程序中将是一场灾难,所以我想这早就被捕获并修复了)。

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

分裂似乎更加微妙。

而且,由于缺乏通用设计,我怀疑更复杂的事物(三角函数、日志..)的所有实现都可以完全同步,因为可以使用各种数学方法。

我问这个是出于纯粹的爱管闲事;愿意改进我的答案;并且希望有一种方法(有时)允许在 VM 中运行的程序检测假装运行的 CPU 与真实 CPU 之间的不匹配。

4

2 回答 2

13

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

于 2012-10-27T17:25:24.650 回答
2

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

当然,明显的例外是CPUIDMSR 访问。

明显的非例外是各种逻辑、整数和浮点运算。正如Maratyszcza在他的回答中所写,许多更复杂的操作都是通过微码计算的。此微码在具有不同微架构的处理器之间可能会有很大差异,但保证结果是相同的。一方面,英特尔(我没有其他 x86 开发人员的第一手资料)投入大量资源来确保处理器之间的向后兼容性,甚至重现“错误”的行为(将错误更改为新规范)。

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

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

于 2012-10-27T17:49:47.117 回答