为什么不直接访问__m128i字段?

Gid*_*eon 5 c++ sse intrinsics

在MSDN上阅读这篇文章,它说

您不应直接访问__m128i字段.但是,您可以在调试器中看到这些类型.__m128i类型的变量映射到XMM [0-7]寄存器.

但是,它没有解释原因.为什么?例如,以下是"坏":

void func(unsigned short x, unsigned short y)
{
    __m128i a;
    a.m128i_i64[0] = x;

    __m128i b;
    b.m128i_i64[0] = y;

    // Now do something with a and b ...
}
Run Code Online (Sandbox Code Playgroud)

如果使用某种load功能,而不是像上面的例子那样进行分配?

Mys*_*ial 7

字段m128i_i64和系列是Microsoft编译器特定的扩展.它们在大多数其他编译器中不存在.

然而,它们对测试目的很有用.


避免使用它们的真正原因是性能.硬件无法有效访问SIMD向量的各个元素.

  • 没有说明可以让您直接访问单个元素.(SSE4.1可以,但它需要一个编译时常量索引.)
  • 由于存储转发失败,经历内存可能会导致非常大的损失.

AVX和AVX2不扩展SSE4.1指令以允许访问256位向量中的元素.据我所知,AVX512不会用于512位向量.

同样,集内在函数(例如_mm256_set_pd())遇到同样的问题.它们可以作为一系列数据混洗操作来实现.或者通过记忆和承担商店转发摊位.


这引出了一个问题:是否有一种有效的方法可以从标量组件中填充SIMD向量?(或将SIMD向量分成标量组件)

简答:不是.当您使用SIMD时,您需要以矢量化形式完成大量工作.因此初始化开销无关紧要.