_mm_shuffle_ps () équivalent pour les vecteurs entiers (__m128i)?

La _mm_shuffle_ps() insortingnsèque de _mm_shuffle_ps() permet d’entrelacer les entrées float dans les 2 plus bas flottants et les 2 plus hauts flottants de la sortie.

Par exemple:

 R = _mm_shuffle_ps(L1, H1, _MM_SHUFFLE(3,2,3,2)) 

aura pour résultat:

 R[0] = L1[2]; R[1] = L1[3]; R[2] = H1[2]; R[3] = H1[3] 

Je voulais savoir s’il y avait un insortingnsèque similaire disponible pour le type de données entier? Quelque chose qui a pris deux variables __m128i et un masque pour l’entrelacement?

_mm_shuffle_epi32() insortingnsèque, prend un seul vecteur 128 bits au lieu de deux.

Non, il n’y a pas d’équivalent entier à cela. Il faut donc soit l’imiter, soit sortingcher.

Une méthode consiste à utiliser _mm_shuffle_epi32() sur A et B Puis masquez les termes souhaités et OU les rapprochez.

Cela a tendance à être en désordre et a environ 5 instructions. (Ou 3 si vous utilisez les instructions de mélange SSE4.1.)

Voici la solution SSE4.1 avec 3 instructions:

 __m128i A = _mm_set_epi32(13,12,11,10); __m128i B = _mm_set_epi32(23,22,21,20); A = _mm_shuffle_epi32(A,2*1 + 3*4 + 2*16 + 3*64); B = _mm_shuffle_epi32(B,2*1 + 3*4 + 2*16 + 3*64); __m128i C = _mm_blend_epi16(A,B,0xf0); 

La méthode que je préfère consiste à sortingcher – et à mélanger en virgule flottante comme ceci:

 __m128i Ai,Bi,Ci; __m128 Af,Bf,Cf; Af = _mm_castsi128_ps(Ai); Bf = _mm_castsi128_ps(Bi); Cf = _mm_shuffle_ps(Af,Bf,_MM_SHUFFLE(3,2,3,2)); Ci = _mm_castps_si128(Cf); 

Ce que cela fait est de convertir le type de données en virgule flottante afin qu’il puisse utiliser le float-shuffle. Puis reconvertissez-le.

Notez que ces “conversions” sont des conversions au niveau des bits (réinterprétations). Aucune conversion n’est réellement effectuée et ils ne correspondent à aucune instruction. Dans l’assemblage, il n’y a pas de distinction entre un registre SSE à nombre entier ou à virgule flottante. Ces éléments insortingnsèques sont juste pour contourner la sécurité de type imposée par C / C ++.

Sachez toutefois que cette approche entraîne une latence supplémentaire pour le déplacement des données entre les unités d’exécution SIMD à nombres entiers et à virgule flottante. Ce sera donc plus cher que la simple instruction de lecture aléatoire.