How to choose AVX compare predicate variants
在高级向量扩展(AVX)中,比较指令(如_m256_cmp_ps),最后一个参数是比较谓词。
谓词的选择使我不知所措。
它们似乎是类型,排序,信号的三倍。
例如。 _CMP_LE_OS是"小于或等于有序信令"。
对于初学者来说,是否出于性能原因选择信令或非信令,
并且类似地,有序或无序比另一个更快?
"无信号"甚至意味着什么?
我根本找不到在文档中。
关于何时选择什么的任何经验法则?
以下是来自avxintrin.h的谓词选择:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /* Compare */ #define _CMP_EQ_OQ 0x00 /* Equal (ordered, non-signaling) */ #define _CMP_LT_OS 0x01 /* Less-than (ordered, signaling) */ #define _CMP_LE_OS 0x02 /* Less-than-or-equal (ordered, signaling) */ #define _CMP_UNORD_Q 0x03 /* Unordered (non-signaling) */ #define _CMP_NEQ_UQ 0x04 /* Not-equal (unordered, non-signaling) */ #define _CMP_NLT_US 0x05 /* Not-less-than (unordered, signaling) */ #define _CMP_NLE_US 0x06 /* Not-less-than-or-equal (unordered, signaling) */ #define _CMP_ORD_Q 0x07 /* Ordered (nonsignaling) */ #define _CMP_EQ_UQ 0x08 /* Equal (unordered, non-signaling) */ #define _CMP_NGE_US 0x09 /* Not-greater-than-or-equal (unord, signaling) */ #define _CMP_NGT_US 0x0a /* Not-greater-than (unordered, signaling) */ #define _CMP_FALSE_OQ 0x0b /* False (ordered, non-signaling) */ #define _CMP_NEQ_OQ 0x0c /* Not-equal (ordered, non-signaling) */ #define _CMP_GE_OS 0x0d /* Greater-than-or-equal (ordered, signaling) */ #define _CMP_GT_OS 0x0e /* Greater-than (ordered, signaling) */ #define _CMP_TRUE_UQ 0x0f /* True (unordered, non-signaling) */ #define _CMP_EQ_OS 0x10 /* Equal (ordered, signaling) */ #define _CMP_LT_OQ 0x11 /* Less-than (ordered, non-signaling) */ #define _CMP_LE_OQ 0x12 /* Less-than-or-equal (ordered, non-signaling) */ #define _CMP_UNORD_S 0x13 /* Unordered (signaling) */ #define _CMP_NEQ_US 0x14 /* Not-equal (unordered, signaling) */ #define _CMP_NLT_UQ 0x15 /* Not-less-than (unordered, non-signaling) */ #define _CMP_NLE_UQ 0x16 /* Not-less-than-or-equal (unord, non-signaling) */ #define _CMP_ORD_S 0x17 /* Ordered (signaling) */ #define _CMP_EQ_US 0x18 /* Equal (unordered, signaling) */ #define _CMP_NGE_UQ 0x19 /* Not-greater-than-or-equal (unord, non-sign) */ #define _CMP_NGT_UQ 0x1a /* Not-greater-than (unordered, non-signaling) */ #define _CMP_FALSE_OS 0x1b /* False (ordered, signaling) */ #define _CMP_NEQ_OS 0x1c /* Not-equal (ordered, signaling) */ #define _CMP_GE_OQ 0x1d /* Greater-than-or-equal (ordered, non-signaling) */ #define _CMP_GT_OQ 0x1e /* Greater-than (ordered, non-signaling) */ #define _CMP_TRUE_US 0x1f /* True (unordered, signaling) */ |
有序与无序的关系在于,如果其中一个操作数包含NaN,则比较是否为真(请参阅有序/无序比较是什么意思?)。信令(S)与非信令(Q表示安静吗?)将确定是否在操作数包含NaN的情况下引发异常。
从性能的angular来看,这些都应该是相同的(假设当然不会引发异常)。如果要在出现NaN时收到警报,则需要发信号。至于有序与无序,这都取决于您要如何处理NaN。
当任一操作数为NaN时,有序与无序指示结果值。
有序比较返回NaN操作数的
-
1.0 和1.0 的_CMP_EQ_OQ给出true (原始等式)。 -
NaN 和1.0 的_CMP_EQ_OQ给出false 。 -
1.0 和NaN 的_CMP_EQ_OQ给出false 。 -
NaN 和NaN 的_CMP_EQ_OQ给出false 。
无序比较返回NaN操作数的
-
1.0 和1.0 的_CMP_EQ_UQ给出true (原始等式)。 -
NaN 和1.0 的_CMP_EQ_UQ给出true 。 -
1.0 和NaN 的_CMP_EQ_UQ给出true 。 -
NaN 和NaN 的_CMP_EQ_UQ给出true 。
信令与非信令之间的差异仅影响MXCSR的价值。要观察效果,??您需要清除MXCSR,执行一个或多个比较,然后从MXCSR中读取(感谢Peter Cordes阐明了这一点!)。
枚举值的顺序非常混乱。将它们放在表格中会有所帮助...
比较 th> | 无序(无信号) th> | 无序(无信号) th> tr> thead> | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
a | _ CMP_LT_OQ td> | _ CMP_NGE_UQ td> tr> | ||||||||||||||||||||||||||
a <= b td> < td style =" text-align:" center;" ="> _ CMP_LE_OQ td> | _ CMP_NGT_UQ td> tr> | |||||||||||||||||||||||||||
a == b td> | _ CMP_EQ_OQ td> | tr> | ||||||||||||||||||||||||||
a!= b td> | _ CMP_NEQ_OQ td> | _ CMP_NEQ_UQ td> tr> | ||||||||||||||||||||||||||
a> = b td> | _ CMP_GE_OQ td> | _ CMP_NLT _UQ td> tr> | ||||||||||||||||||||||||||
a> b td> | _CMP_GT_OQ td> | _ CMP_NLE_UQ td> tr> | ||||||||||||||||||||||||||
true td> | _ CMP_ORD_Q td> | _ CMP_TRUE_UQ(无用) td> tr> | ||||||||||||||||||||||||||
false td> | _ CMP_FALSE_OQ(无用) td> | _ CMP_UNORD_Q td> tr> tbody> table>
使用MXCSR"信号发送":
|