用于GCC划分的SIMD(SSE)指令
如果可能,我想使用SSE指令优化以下代码段:
/* * the data structure */ typedef struct v3d v3d; struct v3d { double x; double y; double z; } tmp = { 1.0, 2.0, 3.0 }; /* * the part that should be "optimized" */ tmp.x /= 4.0; tmp.y /= 4.0; tmp.z /= 4.0;
这有可能吗?
我在windows下使用了SIMD扩展,但还没有在linux下。 话虽这么说你应该能够利用DIVPS
SSE操作,它将4浮点向量除以另外4个浮点向量。 但是你正在使用双打,所以你需要SSE2版本的DIVPD
。 我差点忘了,确保使用-msse2
开关构建。
我找到了一个页面,详细介绍了一些SSE GCC内置版本。 它看起来有点旧,但应该是一个好的开始。
是tmp.x *= 0.25;
足够?
请注意,对于SSE指令(如果您要使用它们),重要的是:
1)所有内存访问都是16字节对齐
2)操作在循环中执行
3)没有int < - > float或float < - >执行双重转换
4)尽可能避免分裂
您正在寻找的内在因素是_mm_div_pd
。 这是一个充分的工作示例,足以引导您朝着正确的方向前进:
#include #include typedef struct { double x; double y; double z; } v3d; typedef union __attribute__ ((aligned(16))) { v3d a; __m128d v[2]; } u3d; int main(void) { const __m128d vd = _mm_set1_pd(4.0); u3d u = { { 1.0, 2.0, 3.0 } }; printf("v (before) = { %g %g %g }\n", uax, uay, uaz); uv[0] = _mm_div_pd(uv[0], vd); uv[1] = _mm_div_pd(uv[1], vd); printf("v (after) = { %g %g %g }\n", uax, uay, uaz); return 0; }