2017-06-25 7 views
2

J'ai un vecteur de 128 bits de 4 flotteurs qui ont été calculés, et je veux changer l'ordre de ce vecteur comme ceci:Comment puis-je réorganiser un vecteur 128 bits à l'aide d'Intel intrinsics?

Vector A before reordering 
+---+---+---+---+ 
| a | b | c | d | 
+---+---+---+---+ 

Vector A after reordering 
+---+---+---+---+ 
| b | a | c | d | 
+---+---+---+---+ 

Comme je l'ai dit le vecteur a été calculé par des calculs donc plus tôt façon d'utiliser _mm_set_ps() ... Quelqu'un at-il une idée sur la façon dont cela peut-il être fait?

+2

Compiler '__m128 f (__ M128 x) {return _mm_setr_ps (x, x [0] [1], x [2], x [3]);} 'avec gcc ou clang et' -O3 -msse4' donne 'shufps \t $ 225,% xmm0,% xmm0', ressemble à un indice fort ... –

+2

Voir https://software.intel.com/sites/landingpage/IntrinsicsGuide/pour un outil de recherche pratique, et d'autres liens dans le [sse tag wiki] (https://stackoverflow.com/tags/sse/info), ainsi que le [wiki tag x86] (https: //stackoverflow.com/tags/x86/info). Si vous trouvez que votre code contient trop de shuffles, pensez à réorganiser vos structures de données, ou comment vous vectoriser une boucle imbriquée, afin de réduire autant que possible le réarrangement. –

Répondre

6

Vous recherchez le SHUFPS instruction (shuffle emballé flotteurs de précision).
Le correspondant intrinsèque est _mm_shuffle_ps:

__m128 _mm_shuffle_ps(__m128 a, __m128 b, unsigned int imm8); 

Le troisième paramètre, immédiatement d'une 8-bit, est la permutation. Ceci indique comment vous voulez que les valeurs soient mélangées. Pour créer cela de manière lisible, vous devez utiliser la macro _MM_SHUFFLE. Voici une description graphique utile de la façon dont _MM_SHUFFLE œuvres, provenant some old Microsoft documentation:

+1

Est-ce qu'un compilateur reconnaîtra quand le registre xmm de destination est le même que le premier registre source xmm (m3 == m1) pour qu'il effectue un shuffle in place (avec une seule insertion SHUFPS) plutôt qu'un registre temp xmm? – rcgldr

+2

[Oui, ce sera] (https://godbolt.org/g/11o5LZ), @rcgldr. –

+0

Je saute habituellement '_MM_SHUFFLE' et l'écris comme base quatre et puis convertis en base 16. 1032 dans la base quatre devient (1 * 4 + 0) * 16 + (3 * 4 + 2) = 0x4E. –