C++ 了解_m128i标志的位对齐
我试图理解SSE strstr的实现,有一个特定的函数正在做一些我不太理解的事情:wrt将一个C++ 了解_m128i标志的位对齐,c++,c,simd,intrinsics,C++,C,Simd,Intrinsics,我试图理解SSE strstr的实现,有一个特定的函数正在做一些我不太理解的事情:wrt将一个const unsigned char*加载到\uuuum128i中。该函数是\u m128i\u strloadu函数(取自此处:): 我觉得这是一个简单的对齐到16位的操作,但是我在可视化/如何/它发生时遇到了困难。movemask比较在这里完成了什么/它检查了什么?它正在测试字符串的结尾是否在这个块中,如果是,它将多余的字节移出并返回。否则,它将继续执行正常的未对齐加载,避免移位并包含“更多字符串
const unsigned char*
加载到\uuuum128i
中。该函数是\u m128i\u strloadu
函数(取自此处:):
我觉得这是一个简单的对齐到16位的操作,但是我在可视化/如何/它发生时遇到了困难。movemask比较在这里完成了什么/它检查了什么?它正在测试字符串的结尾是否在这个块中,如果是,它将多余的字节移出并返回。否则,它将继续执行正常的未对齐加载,避免移位并包含“更多字符串”,而不是伪零
掩码是16字节块中字节为零的掩码
bmsk>>偏移量
是掩码的一部分,表示请求的字节(从p
开始),额外的字节是由于对齐而产生的。啊,完全有意义。谢谢
static inline __m128i __m128i_strloadu (const unsigned char * p) {
int offset = ((size_t) p & (16 - 1));
if (offset && (int) ((size_t) p & 0xfff) > 0xff0) {
__m128i a = _mm_load_si128 ((__m128i *) (p - offset));
__m128i zero = _mm_setzero_si128 ();
// I don't understand what this movemask, in concert
// with the shift right comparison below, are accomplishing
int bmsk = _mm_movemask_epi8 (_mm_cmpeq_epi8 (a, zero));
if ((bmsk >> offset) != 0) {
return __m128i_shift_right(a, offset);
}
}
return _mm_loadu_si128 ((__m128i *) p);
}