问题描述
x87 FPU 以使用内部 80 位精度模式而著称,这通常会导致跨编译器和机器产生意外且不可重现的结果.在我的搜索中在 .NET 上可重现的浮点数学,我发现 .NET(Microsoft 和 Mono)的两个主要实现都发出 SSE 指令,而不是 64 位模式下的 x87.
The x87 FPU is notable for using an internal 80-bit precision mode, which often leads to unexpected and unreproducible results across compilers and machines. In my search for reproducible floating-point math on .NET, I discovered that both major implementations of .NET (Microsoft's and Mono) emit SSE instructions rather than x87 in 64-bit mode.
SSE(2) 对 32 位浮点数使用严格的 32 位寄存器,对 64 位浮点数使用严格的 64 位寄存器.通过设置适当的控制字,可以选择将非规范化刷新为零.
SSE(2) uses strictly 32-bit registers for 32-bit floats, and strictly 64-bit registers for 64-bit floats. Denormals can optionally be flushed to zero by setting the appropriate control word.
因此,SSE 似乎不受 x87 精度相关问题的影响,唯一的变量是可以控制的异常行为.
It would therefore appear that SSE does not suffer from the precision-related issues of x87, and that the only variable is the denormal behavior, which can be controlled.
撇开先验函数(与 x87 不同,SSE 本身不提供这些函数)的问题,使用 SSE 是否能保证跨机器和编译器的可重现结果?例如,编译器优化能否转化为不同的结果?我发现了一些相互矛盾的意见:
Leaving aside the matter of transcendental functions (which are not natively provided by SSE unlike x87), does using SSE guarantee reproducible results across machines and compilers? Could compiler optimizations, for instance, translate into different results? I found some conflicting opinions:
如果您拥有 SSE2,请使用它并从此过上幸福的生活.SSE2 支持32b 和 64b 操作和中间结果都是操作数的大小.- Yossi Kreinin,http://www.yosefk.com/blog/consistency-how-to-defeat-the- purpose-of-ieee-floating-point.html
If you have SSE2, use it and live happily ever after. SSE2 supports both 32b and 64b operations and the intermediate results are of the size of the operands. - Yossi Kreinin, http://www.yosefk.com/blog/consistency-how-to-defeat-the-purpose-of-ieee-floating-point.html
...
SSE2 指令 (...) 完全符合 IEEE754-1985,并且它们允许更好的再现性(由于静态舍入精度)和与其他平台的可移植性.穆勒等人,浮点算术手册 - p.107
The SSE2 instructions (...) are fully IEEE754-1985 compliant, and they permit better reproducibility (thanks to the static rounding precision) and portability with other platforms. Muller et aliis, Handbook of Floating-Point Arithmetic - p.107
然而:
此外,您不能将 SSE 或 SSE2 用于浮点,因为它太未指定为确定性的.- 约翰·瓦特http://www.gamedev.net/topic/499435-floating-点确定性/#entry4259411
Also, you can't use SSE or SSE2 for floating point, because it's too under-specified to be deterministic. - John Watte http://www.gamedev.net/topic/499435-floating-point-determinism/#entry4259411
推荐答案
SSE 已完全指定*.Muller 是浮点运算方面的专家;你会相信谁,他还是游戏开发论坛上的某个人?
SSE is fully specified*. Muller is an expert in floating point arithmetic; who are you going to trust, him or some guy on a gamedev forum?
(*) 实际上,对于 rsqrtss 等非 IEEE-754 操作有一些例外,英特尔从未完全指定行为,但这不会影响 IEEE-754 基本操作,更重要的是它们的行为可以t 实际上在这一点上改变,因为它会破坏太多东西的二进制兼容性,所以它们和指定的一样好.
(*) there are actually a few exceptions for non-IEEE-754 operations like rsqrtss, where Intel never fully specified the behavior, but that doesn't effect the IEEE-754 basic operations, and more importantly their behavior can't actually change at this point because it would break binary compatibility for too many things, so they're as good as specified.
这篇关于SSE 浮点算术是否可重现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!