通常我使用以下类型处理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
答案 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
提供的解决方案没有此问题。