测试 NEON SIMD 寄存器在所有通道上的相等性

Testing NEON SIMD registers for equality over all lanes

我正在使用 Neon Instrinics 和 clang。

我想测试两个 uint32x4_t SIMD 值在所有通道上的相等性。 所以不是 4 个测试结果,而是一个单一的结果告诉我 A 和 B 是否对所有车道都相等。

在 Intel AVX 上,我会使用类似的东西:

_mm256_testz_si256( _mm256_xor_si256( A, B ), _mm256_set1_epi64x( -1 ) )

对 NEON SIMD 执行全通道相等性测试的好方法是什么?

我假设我需要跨通道运行的内在函数。 ARM Neon 是否具有这些功能?

试试这个:

uint16x4_t t = vqmovn_u32(veorq_u32(a, b));
vget_lane_u64(vreinterpret_u64_u16(t), 0) == 0

我希望编译器在实施该测试时找到特定于目标的优化。


我刚刚意识到一些有用的东西...

如果你想测试所有车道都小于2的某个幂,你可以用vqshrn_n_u32()替换vqmovn_u32();我相信对于使用 vqrshrn_n_s32() 的签名类型,这可以扩展到 +/- 2 的幂(包括下限,不包括上限)。例如,您应该能够在使用 vqrshrn_n_s32(x, 1).

的单个测试中同时接受 -1 和 0

如果您只想知道两个向量是否相等,请尝试以下代码:

result = vceqq_u32(a, b);
if (vminvq_u32(result ) != 0xffffffff) {
     // not equal
} else {
     // equal
}

查看 ARM 手册:CMEQ and UMINV