C - 如何使用GCC SSE向量扩展访问向量元素

时间:2009-11-20 17:12:17

标签: gcc sse

通常我使用以下类型处理3D矢量:

typedef vec3_t float[3];

使用smth初始化向量。像:

vec3_t x_basis = {1.0, 0.0, 0.0};
vec3_t y_basis = {0.0, 1.0, 0.0};
vec3_t z_basis = {0.0, 0.0, 1.0};

并使用smth访问它们。像:

x_basis[X] * y_basis[X] + ...

现在我需要一个使用SSE指令的矢量算术。我有以下代码:

typedef float v4sf __attribute__ ((mode(V4SF)))
int main(void)
{
    v4sf   a,b,c;
    a = (v4sf){0.1f,0.2f,0.3f,0.4f};
    b = (v4sf){0.1f,0.2f,0.3f,0.4f};
    c = (v4sf){0.1f,0.2f,0.3f,0.4f};
    a = b + c;
    printf("a=%f \n", a);
    return 0;
}

GCC支持这种方式。但... 首先,它给我0.00000作为结果。其次,我无法访问这些向量的元素。 我的问题是:我如何访问这些载体的元素?我需要smth。像[0]访问X元素,[1]访问Y元素等

PS:我使用以下代码编译此代码:

gcc -msse testgcc.c -o testgcc

3 个答案:

答案 0 :(得分:17)

访问元素的安全和推荐方法是使用union而不是指针类型punning,这会欺骗编译器的别名检测机制,并可能导致代码不稳定。

union Vec4 {
    v4sf v;
    float e[4];
};

Vec4 vec;
vec.v = (v4sf){0.1f,0.2f,0.3f,0.4f};
printf("%f %f %f %f\n", vec.e[0], vec.e[1], vec.e[2], vec.e[3]);

答案 1 :(得分:6)

请注意,gcc 4.6现在supports下标向量:

  

在C向量中可以下标,就像向量是具有相同数量的元素和基本类型的数组一样。超出限制的访问在运行时调用未定义的行为。可以使用-Warray-bounds启用向量订阅的超出限制访问警告。

答案 2 :(得分:5)

您忘记了需要将a重新解释为浮点数组。以下代码正常运行:

int main(){
    v4sf a,b,c;
    a = (v4sf){0.1f,0.2f,0.3f,0.4f};
    b = (v4sf){0.1f,0.2f,0.3f,0.4f};
    c = (v4sf){0.1f,0.2f,0.3f,0.4f};
    a = b + c;
    float* pA = (float*) &a;
    printf("a=[%f %f %f %f]\n",pA[0], pA[1], pA[2], pA[3]);
    return 0;
}

P.S。:感谢这个问题,我不知道gcc有这样的SSE支持。

更新:一旦数组未对齐,此解决方案将失败。 @drhirsh提供的解决方案没有此问题。