短版:无序是两个 FP 值可以具有的关系。标量比较设置的 FLAGS,因此您可以检查您想要的任何条件(例如 ucomisd xmm0, xmm1 / jp unordered),但 SIMD 比较需要将条件(谓词)编码到要并行检查的指令中,以生成元素值为0 / 0xFF.... 无处为每个元素放置单独的 FLAGS 结果。
FUCOM 中的“无序”表示当比较结果无序时它不会引发 FP“无效”异常,而 FCOM 会。这与 OQ 和 OS cmpps 谓词之间的区别相同,而不是“无序”谓词。 (见“信号
#IA 开启
英特尔 asm 手册中cmppd 文档中的“QNAN”列。(cmppd 按字母顺序排列,文档更完整,与 cmpps / cmpss/sd 相比))
(FP exceptions 默认情况下被屏蔽,因此它们不会导致 CPU 陷入硬件异常处理程序,只需在 MXCSR 中设置粘性标志,或为 x87 指令设置传统 x87 状态字。)
ORD 和 UNORD 是 cmppd / cmpps / cmpss / cmpsd insns (full tables in the cmppd entry which is alphabetically first) 的两个谓词选择。该 html 提取具有可读的表格格式,但英特尔的官方 PDF 原件要好一些。 (有关链接,请参阅x86 标签 wiki)。
两个浮点如果都不是NaN,则操作数相互排序。如果其中一个是 NaN,则它们是无序的。即ordered = (x>y) | (x==y) | (x<y);。没错,使用浮点数,这些事情都不可能是真的。更多浮点疯狂,见Bruce Dawson's excellent series of articles.
cmpps 接受一个谓词并产生一个结果向量,而不是在两个标量之间进行比较并设置标志,这样您就可以在事后检查您想要的任何谓词。因此,它需要特定的谓词来检查您可以检查的所有内容。
标量等效项是 comiss / ucomiss 从 FP 比较结果中设置 ZF/PF/CF(其工作方式类似于 x87 比较指令(请参阅此答案的最后一部分),但在低元素XMM 规则)。
要检查无序,请查看PF。如果比较是有序的,您可以查看其他标志以查看操作数是更大、等于还是小于 (using the same conditions as for unsigned integers, like jae for Above or Equal)。
The COMISS instruction 与 UCOMISS 指令的不同之处在于,当源操作数是 QNaN 或 SNaN 时,它会发出 SIMD 浮点无效操作异常 (#I) 信号。仅当源操作数是 SNaN 时,UCOMISS 指令才会发出无效数值异常。
(SNaN 不是自然发生的;sqrt(-1) 或 inf - inf 之类的操作会在屏蔽异常时产生 QNaN,否则会陷入陷阱并且不会产生结果。)
通常 FP 异常会被屏蔽,因此这实际上不会中断您的程序;它只是在 MXCSR 中设置位,您可以稍后检查。
这与 cmpps / vcmpps 的 O/UQ 与 O/US 风格的谓词相同。 cmp[ps][sd] 指令的 AVX 版本有一个扩展的谓词选择,因此他们需要一个命名约定来跟踪它们。
当操作数无序时,O vs. U 告诉您谓词是否为真。
Q 与 S 告诉您如果任一操作数是 Quiet NaN,是否会引发 #I。 #I 如果任一操作数是 Signaling NaN,将始终被引发,但这些都不是“自然发生的”。您不能将它们作为其他操作的输出,只能通过自己创建位模式(例如,作为函数的错误返回值,以确保以后检测到问题)。
x87 等效项是使用fcom 或fucom 设置FPU 状态字-> fstsw ax -> sahf,或者最好使用fucomi 直接设置EFLAGS,如ucomiss。
x87 指令的 U / 非 U 区别与 comiss / ucomiss 相同