如何选择AVX比较谓词变体

时间:2013-06-07 15:52:37

标签: simd avx

在高级向量扩展(AVX)中,比较指令如_m256_cmp_ps,最后一个参数是比较谓词。 谓词的选择压倒了我。 它们似乎是类型,排序,信号的三重奏。 例如。 _CMP_LE_OS'小于或等于,有序,发信号。

对于初学者来说,是否存在选择信令或非信令的性能原因, 同样地,有序或无序的速度比另一个更快?

'非信令'甚至意味着什么? 我根本无法在文档中找到这个。 关于何时选择什么的任何经验法则?

以下是avxintrin.h的谓词选择:

/* 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)  */

2 个答案:

答案 0 :(得分:28)

Ordered vs Unordered与其中一个操作数包含NaN(参见What does ordered / unordered comparison mean?)的比较是否为真有关。信令(S)与非信令(Q表示安静?)将确定如果操作数包含NaN则是否引发异常。

从性能的角度来看,这些都应该是相同的(当然假设没有例外)。如果您希望在有NaN时收到警报,那么您需要发出信号。对于有序与无序,这一切都取决于你想如何处理NaN。

答案 1 :(得分:2)

当一个或多个操作数为NaN时,有序与无序指示结果值。

当操作数之一为NaN时,有序比较将返回false

  • 1.01.0的_CMP_EQ_OQ给出true(香草平等)。
  • NaN1.0的_CMP_EQ_OQ给出false
  • 1.0NaN的_CMP_EQ_OQ给出false
  • NaNNaN的_CMP_EQ_OQ给出false

无序比较对于NaN操作数具有完全相反的行为:

  • 1.01.0的_CMP_EQ_UQ给出true(香草平等)。
  • NaN1.0的_CMP_EQ_UQ给出true
  • 1.0NaN的_CMP_EQ_UQ给出true
  • NaNNaN的_CMP_EQ_UQ给出true

预期 ,当其中一个操作数为NaN时,使用“信号”比较器会触发错误,但事实并非如此。老实说,我无法弄清楚信号变种的作用。

请注意,并非所有运算符组合都是直接定义的,但是可以使用定义的那些来模拟“缺失”运算符:

  • <=>=操作数没有定义,但是可以通过交换操作数的顺序并使用><来模拟它们,因为a <= bb < a相同。请注意,如果操作数之一是NaN,您仍然会得到false,因此这仍然是“有序的” NaN行为。

  • 对于<>,只有有序的变体(例如_CMP_LT_OQ)具有一流的枚举值,但两个变体都存在。要获得无序行为,请查找_CMP_NGE_UQ,因为a < b等效于!(a >= b)。这些名称使整体列表更容易混淆。