Instruction SIMD (SSE) pour la division en GCC

J’aimerais optimiser l’extrait de code suivant à l’aide des instructions SSE, si possible:

/* * 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; 

Est-ce possible?

J’ai utilisé l’extension SIMD sous Windows, mais pas encore sous Linux. Cela étant dit, vous devriez pouvoir tirer parti de l’opération DIVPS SSE qui divisera un vecteur à 4 DIVPS par un autre vecteur à 4 float. Mais vous utilisez des doublons, vous aurez donc besoin de la version DIVPD SSE2. J’ai presque oublié, assurez-vous de construire avec le commutateur -msse2 .

J’ai trouvé une page qui détaille certaines modifications intégrées de SSE GCC. Ça a l’air un peu vieux, mais ça devrait être un bon début.

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

Est tmp.x *= 0.25; assez?

Notez que pour les instructions SSE (au cas où vous voudriez les utiliser), il est important que:

1) tout l’access mémoire est de 16 octets alighed

2) les opérations sont effectuées en boucle

3) pas de conversion int <-> float ou float <-> double

4) éviter les divisions si possible

L’insortingnsèque que vous recherchez est _mm_div_pd . Voici un exemple pratique qui devrait suffire à vous orienter dans la bonne direction:

 #include  #include  typedef struct { double x; double y; double z; } v3d; typedef union __atsortingbute__ ((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; }