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

Posted

技术标签:

【中文标题】loadu/lddqu 和赋值运算符有啥区别?【英文标题】:What is the difference between loadu/lddqu and assignment operator?loadu/lddqu 和赋值运算符有什么区别? 【发布时间】:2020-04-29 14:21:00 【问题描述】:

我正在使用SIMD向量进行一些计算,并好奇它们的区别,如下。

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

那么,以上两种说法有什么区别呢?

【问题讨论】:

第二个就像写x = *&y - 它无缘无故地变得更加复杂。 (假设vector1 的类型为__m128i 【参考方案1】:

就像 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 等,但即使这样也不太正确,因为数据不需要与_Alignof(int)_Alignof(short)etc.,虽然 char 实际上在这里工作得很好。

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

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

【讨论】:

以上是关于loadu/lddqu 和赋值运算符有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

+=和=+ C赋值运算符有啥区别[重复]

C++中赋值运算操作符和=重载有啥区别?

python中的两个赋值运算符有啥区别? [复制]

= 和 == 有啥区别?

C语言中的一个等号和两个等号有啥区别

切片整个列表的切片赋值和直接赋值有啥区别?