9

通常我使用以下类型处理 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。比如 a[0] 访问 X 元素, a[1] 访问 Y 元素等。

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

gcc -msse testgcc.c -o testgcc
4

3 回答 3

17

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

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]);

于 2009-11-20T18:44:15.053 回答
6

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

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

于 2011-05-05T16:35:49.747 回答
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;
}

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

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

于 2009-11-20T17:38:23.563 回答