问题描述
我将 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
移动掩码。额外的指令肯定会消耗延迟,并会在管道中占用一个插槽以提高吞吐量。