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

时间:2014-04-04 17:42:24

标签: c++ sse intrinsics

我正在阅读this on 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 ...
}

如果使用某种load函数,而不是像上面的示例中那样进行分配?

1 个答案:

答案 0 :(得分:6)

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

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


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

  • 没有说明可以让您直接访问单个元素。 (SSE4.1可以,但它需要编译时常量索引。)
  • 由于store forwarding失败,经历记忆可能会受到很大的惩罚。

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

同样,set内在函数(例如_mm256_set_pd())也会遇到同样的问题。它们可以作为一系列数据混洗操作来实现。或者通过记忆并接受商店转发摊位。


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

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