是否可以访问__m128变量中的内部值作为C++类中的属性

Is it possible to access internal values in a __m128 variable as attribute in a C++ class?

本文关键字:C++ 属性 内部 m128 变量 是否 访问      更新时间:2023-10-16

我希望有一个用SSE内部函数实现的Vector类(表示3个浮点的向量)(因此我不会使用__m128类型的第4个元素)。但我希望能够像访问属性一样轻松地访问它们:所以myVector.x将访问vec中的0-31位,myVector.y将访问vec中的32-63位,但不必调用一些getX()方法。"x"属性将是"vec"的0-31位的某种别名。有可能吗?

class Vector {  
public:  
  float x;  
  float y;  
  float z;  
private:  
  __m128 vec;  
}

否,因为这违反了强别名规则

当然,您可以使用强制转换或并集来假装__m128是一个浮点数组,但优化器不会为您维护一致性,因为您违反了语言的规则。

请参阅什么是严格别名规则?

(根据规则,使用并集进行访问是安全的,但这仅适用于命名并集的情况。获取指向并集成员的指针或引用,然后稍后直接使用该指针或引用是不安全的。)

您也许可以使用联合,类似

union data
{
    float[4] xyz;
    __m128 vec;
} aVec;

则浮动将是aVec.xyz[0]aVec.xyz[1]aVec.xyz[2],而__m128将是aVec.vecfloat数组在这里有四个元素,但没有说明必须使用第四个元素。

您可以编写一个结构,自动转换为__m128:

struct alignas(16) Vec4f
{
    float x, y, z, w;
    operator __m128() const { return _mm_load_ps(&x);}
    Vec4f(__m128 const v) { _mm_store_ps(&x, v);}
};

这样做的缺点是Vec4f将通过两个SSE寄存器而不是一个来传递(当通过值传递时:https://godbolt.org/z/sutmuM)。

总的来说,我建议制作一个只包含__m128和重载x()y()等方法的结构。如果可能的话,无论如何都应该避免SSE寄存器上的元素操作(使用第零个元素除外)。

注意:alignas(16)需要C++11,大多数编译器都有特定于编译器的替代方案。或者,也可以使用_mm_loadu_ps_mm_storeu_ps