我正在使用 SIMD 向量进行一些计算,并好奇它们的区别,如下所示。
__m128i vector2 = vector1;
__m128i vector2 = _mm_loadu_si128(&vector1);
那么,以上两种说法有什么区别呢?
我正在使用 SIMD 向量进行一些计算,并好奇它们的区别,如下所示。
__m128i vector2 = vector1;
__m128i vector2 = _mm_loadu_si128(&vector1);
那么,以上两种说法有什么区别呢?
就像彼得科德斯在他的评论中所说的那样,如果vector1真的是__m128i这样,那只是不必要的复杂。
但是,这不是_mm_loadu_si128. 虽然论点的类型是__m128i const*,但实际上更多的是缺乏好的选择和糟糕的决定。
_mm_loadu_si128实际上是要将任何 16 字节的数据加载到向量寄存器中。如果你想加载已经对齐到 16 字节边界的数据,你应该使用它_mm_load_si128。如果您的数据未与 16 字节边界对齐,则它不是真正的 a __m128i,因此参数的类型充其量是具有误导性的。
英特尔(或任何人)选择使用的__m128i const*原因并不完全清楚,但老实说,没有很多好的选择。 int const*真的没有意义,因为我们试图加载的并不总是 32 位有符号整数。他们本可以制作_mm_loadu_epi8, _mm_loadu_epi16,_mm_loadu_epi32等,但即使这样也不太正确,因为数据不需要与,等_Alignof(int)对齐,尽管实际上在这里工作得很好。_Alignof(short)char
正确的选择可能是提出论点void*,但我猜英特尔想表明他们确实想要 16 字节的数据。 char mem_addr[16]在 C99+ 中可以,但在 C++ 中不行,虽然 SSE2 与 C99 几乎同时出现,但许多编译器不支持 C99(MSVC 仍然不支持!)。
基本上,对于这个函数,忽略参数的类型并阅读描述。