AVX2 的 _mm256_cmp_epi32_mask 模拟
Analog of _mm256_cmp_epi32_mask for AVX2
我有 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
movemask。额外的指令肯定会增加延迟,并在管道中占用一个插槽来提高吞吐量。
我有 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
movemask。额外的指令肯定会增加延迟,并在管道中占用一个插槽来提高吞吐量。