loadu/lddqu 和赋值运算符有什么区别?

What is the difference between loadu/lddqu and assignment operator?

我正在使用SIMD vector做一些计算,好奇它们的区别,如下。

__m128i vector2 = vector1;
__m128i vector2 = _mm_loadu_si128(&vector1);

那么,以上两种说法有什么不同呢?

正如 Peter Cordes 在他的评论中所说,如果 vector1 真的是 __m128i,那就太复杂了。

然而,这不是 _mm_loadu_si128 的用例。虽然争论的类型是 __m128i const*,但实际上更多的是缺乏好的选择和糟糕的决定。

_mm_loadu_si128 的真正意思是将任意 16 字节的数据加载到向量寄存器中。如果你想加载已经对齐到 16 字节边界的数据,你应该使用 _mm_load_si128 代替。如果您的数据未与 16 字节边界对齐,则它不是 真正的 __m128i,因此参数类型充其量只是误导。

英特尔(或任何人)选择使用 __m128i const* 的原因尚不完全清楚,但老实说,没有太多好的选择。 int const* 没有意义,因为我们要加载的并不总是 32 位有符号整数。他们本可以制作 _mm_loadu_epi8_mm_loadu_epi16_mm_loadu_epi32 等,但即使那样也不太正确,因为数据不需要与 [=22= 对齐]、_Alignof(short),尽管char实际上在这里工作得很好。

正确的选择可能是提出论点 void*,但我猜英特尔想表明他们确实需要 16 字节的数据。 char mem_addr[16] 在 C99+ 中可以,但在 C++ 中不行,虽然 SSE2 与 C99 大约同时出现,但许多编译器不支持 C99(MSVC 仍然不支持!)。

基本上,对于这个函数,忽略参数的类型并阅读描述。