用于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内置版本。 它看起来有点旧,但应该是一个好的开始。

http://ds9a.nl/gcc-simd/

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; }