AVX2 的 _mm256_cmp_epi32_mask 模拟

问题描述

我将 8 个 32 位整数装入 __m256i 寄存器。现在我需要比较两个寄存器中相应的 32 位值。试过

__mmask8 m = _mm256_cmp_epi32_mask(r1,r2,_MM_CMPINT_EQ);

标记相等对。那太好了,但我收到了“非法指令”异常,可能是因为我的处理器不支持 AVX512。

寻找一个类似的内在函数来快速获得相等对的索引。

找到了解决方法(没有_mm256_movemask_epi32);演员在这里合法吗?

__m256i diff = _mm256_cmpeq_epi32(m1,m2);
__m256 m256 = _mm256_castsi256_ps(diff);
int i = _mm256_movemask_ps(m256);

解决方法

是的,cast 内在函数只是 YMM 寄存器中位的重新解释,它 100% 合法,是的,您希望编译器发出的 asm 是 vpcmpeqd / vmovmaskps

或者如果您可以处理每个位重复 4 次,vpmovmskb 也可以,_mm256_movemask_epi8。例如如果您只想测试任何匹配 (i != 0) 或所有匹配 (i == 0xffffffff),您可以避免对整数结果使用 ps 指令,这可能会花费 1 个额外的绕过周期关键路径中的延迟。

但是如果这会花费你额外的指令,例如在使用 _mm_tzcnt_u32 查找元素索引而不是第一个 1 的字节索引后缩放 4,然后使用 _ps 移动掩码。额外的指令肯定会消耗延迟,并会在管道中占用一个插槽以提高吞吐量。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...