AVX2整数比较小于等于

时间:2016-05-25 22:14:46

标签: c integer compare avx avx2

比较<=的两个4x 64位整数AVX向量的最有效方法是什么。

来自英特尔内在指南我们

  • _mm256_cmpgt_epi64(__m256i a, __m256i b) = a&gt; B'/ LI>
  • _mm256_cmpeq_epi64(__m256i a, __m256i b) = a == b

进行比较

  • _mm256_and_si256(__m256i a, __m256i b) = a&amp; B'/ LI>
  • _mm256_andnot_si256(__m256i a, __m256i b) =〜&amp; B'/ LI>
  • _mm256_or_si256(__m256i a, __m256i b) = a | B'/ LI>
  • _mm256_xor_si256(__m256i a, __m256i b) = a ^ b

用于逻辑操作。

我的方法是:

// check = ( a <= b ) = ~(a > b) & 0xF..F
__m256i a = ...
__m256i b = ...
__m256i tmp = _mm256_cmpgt_epi64(a, b)
__m256i check = _mm256_andnot_si256(tmp, _mm256_set1_epi64x(-1))

1 个答案:

答案 0 :(得分:3)

你是对的,没有直接的方法来获得你真正想要的面具,只有一个倒置的面具:A gt B = A nle B

没有vector-NOT指令,所以你需要一个all-1向量以及一个反向向量的额外指令。 (或者是一个全零和_mm256_cmpeq_epi8的向量,但是它不能在_mm256_xor_si256上使用全向量的多个执行端口上运行。)请参阅标记维基性能信息,尤其是Agner Fog的指南。

另一个按位布尔选项_mm256_andn_si256和xor一样好。这不是可交换的,而且在心理上验证你是否正确是稍微复杂一点。 xor-with-all-ones是翻转所有位的好习惯。

在大多数代码中,不是花费反转掩码的指令,而是以相反的方式使用它。

e.g。如果它是blendv的输入,则将操作数的顺序反转为混合。而不是 _mm256_blendv_epi8(a, b, A_le_B_mask),请使用
_mm256_blendv_epi8(b, a, A_nle_B_mask)

如果您要使用面具_mm_and,请改用_mm_andn

如果你要去_mm_movemask并测试全零,你可以改为测试全部。它将编译为cmp eax, -1指令而不是test eax,eax,这同样有效。如果您要对第一个进行比特扫描,则必须将其反转。整数not指令(在movemask结果上使用~)比在向量上执行要便宜。

如果您要进行OR或XOR,那么您只会遇到问题,因为这些指令不具有否定其输入的风格。 (IDK,如果英特尔只是不想添加PORN助记符,但可能PANDPANDN更多地使用,尤其是在变量混合指令之前。