SIMDKR 字符串匹配算法使用
_mm256_movemask_epi8
将 Vector256 转换为 int;
我想在 C# 中实现这个 clang 算法,使用 Vector512 而不是 256,但我找不到方法来实现。
有 Avx2.MoveMask()
,没有 Avx512F/BW/VBMI/DQ.MoveMask
。
const __m256i first = _mm256_set1_epi8(needle[0]);
const __m256i last = _mm256_set1_epi8(needle[m - 1]);
const __m256i block_first1 = _mm256_loadu_si256((const __m256i *)(s + i));
const __m256i block_last1 = _mm256_loadu_si256((const __m256i *)(s + i + m - 1));
const __m256i eq_first1 = _mm256_cmpeq_epi8(first, block_first1);
const __m256i eq_last1 = _mm256_cmpeq_epi8(last, block_last1);
const uint32_t mask1 = _mm256_movemask_epi8(_mm256_and_si256(eq_first1, eq_last1));
我使用位运算将
_mm512_movepi8_mask
替换为:
ulong mask = ((ulong)Avx2.MoveMask(buffer.GetUpper()) << 32) | (uint)Avx2.MoveMask(buffer.GetLower());
这是对的吗?这是最好的表现吗?
AVX512(也在 C# 之外)在提取高位掩码方面与 AVX2 略有不同,
VPMOVMSKB
没有直接的 512 位等效项。在原始 AVX512 中,您可以使用 VPMOVB2M/VPMOVW2M/VPMOVD2M/VPMOVQ2M 系列指令将向量转换为掩码(掩码的 AVX512 概念),然后您可以将掩码从掩码寄存器移动到通用用途使用 kmov
系列指令进行注册。
C# 处理掩码的方式与原始 AVX512 略有不同(掩码也主要通过
Vector512<T>
类型表示,您通常不会将掩码作为整数使用,我还不完全确定这对于掩码操作代码而言),但是您可以结合 Vector512.ExtractMostSignificantBits 来执行这两个步骤(将向量转换为掩码并将其从掩码寄存器移动到通用寄存器)。