2010-07-29 39 views
13

Je cherche la méthode la plus efficace pour renverser le signe sur les quatre flotteurs emballés dans un registre SSE.Signe de basculement sur les flotteurs SSE emballés

Je n'ai pas trouvé d'élément intrinsèque pour cela dans le manuel de développement du logiciel Intel Architecture. Voici les choses que j'ai déjà essayées.

Pour chaque cas, j'ai bouclé le code 10 milliards de fois et obtenu le temps indiqué. J'essaie au moins de correspondre à 4 secondes, il prend mon approche non-SIMD, qui utilise seulement l'opérateur unaire moins.


[48 sec]
_mm_sub_ps(_mm_setzero_ps(), vec);


[32 sec]
_mm_mul_ps(_mm_set1_ps(-1.0f), vec);


[9 sec]

union NegativeMask { 
    int intRep; 
    float fltRep; 
} negMask; 
negMask.intRep = 0x80000000; 

_mm_xor_ps(_mm_set1_ps(negMask.fltRep), vec); 


Le compilateur est gcc 4.2 avec -O3 . Le processeur est un Intel Core 2 Duo.

Répondre

4

Juste pour compléter votre réponse par la documentation gcc sur ces vecteurs builtin:

The types defined in this manner can be used with a subset of normal C 
operations. Currently, GCC will allow using the following operators on 
these types: `+, -, *, /, unary minus, ^, |, &, ~'. 

Il est probablement une bonne idée de coller toujours à ces lorsque cela est possible. Avec de très grandes chances, gcc fournira toujours le code le plus efficace pour ce truc SSE.

Pour vos options de compilation, ajoutez quelque chose de plus spécifique à votre architecture, quelque chose comme -march=native fera dans la plupart des cas.

2

Une leçon de vie sur le codage jusqu'à 3 heures du matin .....

Je ne ai jamais essayé simplement en utilisant le moins unaire sur mon vecteur emballé. Cela compile et a exactement la même performance que l'approche non-SIMD.

+5

Prenez garde cependant - en utilisant des extensions spécifiques à gcc comme celui-ci ce qui rend votre code non portable. –

+0

avez-vous regardé quel code cela génère? – Aktau

21

Cette union est pas vraiment nécessaire, le meilleur de tous les mondes (lisibilité, la vitesse et la portabilité):

_mm_xor_ps(vec, _mm_set1_ps(-0.f))