计算两个 __m256i 变量的元素之间的 logical_and (&&) 的最快方法是什么,寻找任何一对非零元素

What is the fastest way to calculate the logical_and (&&) between elements of two __m256i variables, looking for any pair of non-zero elements

据我所知,C++ 中的整数可以像布尔值一样处理,我们可以有这样的代码:

int a = 6, b = 10;
if (a && b) do something ---> true as both a and b are non-zero

现在,假设我们有:

__m256i a, b;

我需要对 __m256i 中的所有 4 个长变量应用 logical_and (&&),如果一对非零,则 return 为真。我的意思是:

(a[0] && b[0]) || (a[1] && b[1]) || ...

我们是否有用于此目的的 AVX 或 AVX2 快速代码?

我找不到任何用于此目的的直接指令,而且肯定地,使用按位和 (&) 也不一样。任何帮助将不胜感激。

您可以巧妙地将 vpcmpeqqvptest 结合起来:

__m256i mask = _mm256_cmpeq_epi64(a, _mm256_set1_epi64x(0));
bool result = ! _mm256_testc_si256(mask, b);

当且仅当(~mask & b) != 0

result为真
((a[i]==0 ? 0 : -1) & b[i]) != 0 // for some i
// equivalent to
((a[i]==0 ? 0 : b[i])) != 0      // for some i
// equivalent to
a[i]!=0 && b[i]!=0               // for some i

这相当于你想要的。

Godbolt-link(玩转 ab):https://godbolt.org/z/aTjx7vMKd

如果result是循环条件,编译器当然应该直接执行jb/jnb指令而不是setnb.