有序/无序比较是什么意思?
查看上交所运营商
CMPORDPS - ordered compare packed singles
CMPUNORDPS - unordered compare packed singles
有序和无序是什么意思?我在x86指令集中查找了等效指令,它似乎只有无序(FUCOM)。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
有序比较检查两个操作数是否均为
NaN
。相反,无序比较检查任一操作数是否为NaN
。本页提供了更多相关信息:
这里的想法是与
NaN
的比较是不确定的。 (无法决定结果)因此,有序/无序比较会检查情况是否如此。结果:
如果操作数可比较(两个数字都不是 NaN),有序返回 true:
1.0
和1.0
的有序比较给出true< /代码>。
1.0
的有序比较给出false
。NaN
和NaN
的有序比较给出false
。无序比较正好相反:
1.0
和1.0
的无序比较给出false
。1.0
的无序比较给出true
。NaN
的无序比较给出true
。An ordered comparison checks if neither operand is
NaN
. Conversely, an unordered comparison checks if either operand is aNaN
.This page gives some more information on this:
The idea here is that comparisons with
NaN
are indeterminate. (can't decide the result) So an ordered/unordered comparison checks if this is (or isn't) the case.Result:
Ordered return true if the operands are comparable (neither number is NaN):
1.0
and1.0
givestrue
.NaN
and1.0
givesfalse
.NaN
andNaN
givesfalse
.Unordered comparison is the exact opposite:
1.0
and1.0
givesfalse
.NaN
and1.0
givestrue
.NaN
andNaN
givestrue
.此英特尔指南:http://intel80386.com/simd/mmx2-doc.html包含两个相当简单的示例:
区别在于 AND(有序)与 OR(无序)。
This Intel guide: http://intel80386.com/simd/mmx2-doc.html contains examples of the two which are fairly straight-forward:
The difference is AND (ordered) vs OR (unordered).
简短版本:无序是两个 FP 值可以具有的关系。标量比较设置的 FLAGS,以便您可以检查所需的任何条件(例如
ucomisd xmm0, xmm1
/jp unordered
),但 SIMD 比较需要将条件(谓词)编码到要并行检查的指令以生成元素值为 0 / 0xFF 的向量...无处为每个元素放置单独的 FLAGS 结果。FUCOM
中的“Unordered”意味着当比较结果无序时,它不会引发 FP“无效”异常,而FCOM
会引发。这与 OQ 和 OS cmpps 谓词之间的区别相同,而不是“无序”谓词。 (参见“信号#IA 开启
英特尔 asm 手册中的
cmppd
文档中的“QNAN”列。(cmppd
按字母顺序排列在前,并且具有更完整的文档,与 cmpps / cmpss/sd))(FP 异常 默认情况下被屏蔽,因此它们不会导致CPU 捕获硬件异常处理程序,只需在 MXCSR 中设置粘性标志,或为 x87 指令设置旧版 x87 状态字。)
ORD 和 UNORD 是谓词的两种选择
cmppd
/cmpps
/cmpss
/cmpsd
insns (cmppd
条目中的完整表格按字母顺序排列在前面)。该 html 摘录具有可读的表格格式,但是英特尔的官方 PDF 原始版本要好一些(请参阅 x86 标记 wiki 以获得链接)。如果两个浮点操作数都不是 NaN,则它们将相对于彼此排序。如果其中一个为 NaN,则它们是无序的。即
ordered = (x>y) | (x==y) | (x==y) | (x。没错,对于浮点来说,这些事情都不可能是真的。有关浮点疯狂的更多信息,请参阅 Bruce Dawson 的优秀的系列文章。
cmpps
采用谓词并生成结果向量,而不是在两个标量之间进行比较并设置标志,以便您可以在事后检查您想要的任何谓词。因此,它需要针对您可以检查的所有内容提供特定的谓词。标量等效项是
comis
/ucommiss
,用于根据 FP 比较结果设置 ZF/PF/CF(其工作方式类似于 x87 比较指令(请参阅本答案的最后一部分) ,但在 XMM 规则的低元素上)。要检查是否无序,请查看
PF
。如果比较是有序的,您可以查看其他标志来查看操作数是否大于、等于或小于(使用与无符号整数相同的条件,例如jae
表示“高于”或“等于”)。(SNaN 不是自然发生的;如果异常被屏蔽,像
sqrt(-1)
或inf - inf
这样的操作将产生 QNaN,否则捕获并且不产生结果。) FP 异常被屏蔽,因此这实际上不会中断您的程序;它只是设置 MXCSR 中的位,您可以稍后检查。
这与
cmpps
/vcmpps
的 O/UQ 与 O/US 谓词风格相同。 AVX 版本的 cmp[ps][sd] 指令具有扩展的谓词选择,因此它们需要命名约定来跟踪它们。O 与 U 告诉您当操作数无序时谓词是否为真。
Q 与 S 告诉您如果任一操作数是 Quiet NaN,#I 是否会被引发。如果任一操作数是 Signaling NaN,#I 将始终被引发,但这些不是“自然发生的”。您不能将它们作为其他操作的输出,只能通过自己创建位模式(例如作为函数的错误返回值,以确保稍后检测到问题)。
x87 等效方法是使用
fcom
或fucom
来设置 FPU 状态字 ->fstsw 斧头
->sahf
,或者最好是fucomi
直接设置 EFLAGS,如ucomis
。U/非 U 区别与 x87 指令相同,如
comis
/ucommiss
short version: Unordered is a relation two FP values can have. Scalar compares set FLAGS so you can check any condition you want (e.g.
ucomisd xmm0, xmm1
/jp unordered
), but SIMD compares need to encode the condition (predicate) into the instruction to be checked in parallel to produce a vector with element values of 0 / 0xFF.... Nowhere to put a separate FLAGS result for each element.The "Unordered" in
FUCOM
means it doesn't raise an FP "invalid" exception when the comparison result is unordered, whileFCOM
does. This is the same as the distinction between OQ and OScmpps
predicates, not the "unordered" predicate. (See the "Signals#IA on
QNAN" column in the
cmppd
docs in Intel's asm manuals. (cmppd
is alphabetically first and has the more complete docs, vs. cmpps / cmpss/sd))(FP exceptions are masked by default so they don't cause the CPU to trap to a hardware exception handler, just set sticky flags in MXCSR, or the legacy x87 status word for x87 instructions.)
ORD and UNORD are two choices of predicate for the
cmppd
/cmpps
/cmpss
/cmpsd
insns (full tables in thecmppd
entry which is alphabetically first). That html extract has readable table formatting, but Intel's official PDF original is somewhat better. (See the x86 tag wiki for links).Two floating point operands are ordered with respect to each other if neither is NaN. They're unordered if either is NaN. i.e.
ordered = (x>y) | (x==y) | (x<y);
. That's right, with floating point it's possible for none of those things to be true. For more Floating Point madness, see Bruce Dawson's excellent series of articles.cmpps
takes a predicate and produces a vector of results, instead of doing a comparison between two scalars and setting flags so you can check any predicate you want after the fact. So it needs specific predicates for everything you can check.The scalar equivalent is
comiss
/ucomiss
to set ZF/PF/CF from the FP comparison result (which works like the x87 compare instructions (see the last section of this answer), but on the low element of XMM regs).To check for unordered, look at
PF
. If the comparison is ordered, you can look at the other flags to see whether the operands were greater, equal, or less (using the same conditions as for unsigned integers, likejae
for Above or Equal).(SNaN is not naturally occurring; operations like
sqrt(-1)
orinf - inf
will produce QNaN if exceptions are masked, else trap and not produce a result.)Normally FP exceptions are masked, so this doesn't actually interrupt your program; it just sets the bit in the MXCSR which you can check later.
This is the same as O/UQ vs. O/US flavours of predicate for
cmpps
/vcmpps
. The AVX version of thecmp[ps][sd]
instructions have an expanded choice of predicate, so they needed a naming convention to keep track of them.The O vs. U tells you whether the predicate is true when the operands are unordered.
The Q vs. S tells you whether #I will be raised if either operand is a Quiet NaN. #I will always be raised if either operand is a Signalling NaN, but those are not "naturally occurring". You don't get them as outputs from other operations, only by creating the bit pattern yourself (e.g. as an error-return value from a function, to ensure detection of problems later).
The x87 equivalent is using
fcom
orfucom
to set the FPU status word ->fstsw ax
->sahf
, or preferablyfucomi
to set EFLAGS directly likeucomiss
.The U / non-U distinction is the same with x87 instructions as for
comiss
/ucomiss
你可以通过llvm CC的定义来理解“ordered CC”和“unordered CC”的含义,其中“CC”表示CondCode。
在'llvm/include/llvm/CodeGen/ISDOpcodes.h'(我的源代码版本是llvm-10.0.1)中,您可以看到CondCode的枚举如下:
这意味着:对于浮点条件比较,'ordered CC ' 的意思是“订购并” CC',而'无序CC'意味着'无序|抄送'。
换句话说,在浮点比较中,如果 NaN 是“不是数字”,则
您还可以看到,'ordered CC' 绝对与 'unordered !CC' 相反。
You may understand the meaning of 'ordered CC' and 'unordered CC' through llvm CC definition, where 'CC' means CondCode.
In 'llvm/include/llvm/CodeGen/ISDOpcodes.h' (my source code version is llvm-10.0.1), you could see the enum of CondCode as below:
That means: for floating-point condition comparision, 'ordered CC' means 'ordered & CC', while 'unordered CC' means ' unordered | CC'.
In another word, in floating-point comparison, where NaN is 'Not A Number',
You can also see, that 'ordered CC' is definitely the opposite of 'unordered !CC'.
也许此页面在视觉上C++ 内在函数有帮助吗? :)
CMPORDPS
CMPUNORDPS
Perhaps this page on Visual C++ intrinsics can be of help? :)
CMPORDPS
CMPUNORDPS