Obtenir la valeur maximale dans un vecteur __m128i avec SSE?

Je viens de commencer à utiliser SSE et je ne comprends pas comment obtenir la valeur entière maximale ( max ) d’un __m128i . Par exemple:

 __m128i t = _mm_setr_ps(0,1,2,3); // max(t) = 3; 

Rechercher autour de moi m’a conduit à l’instruction MAXPS mais je n’arrive pas à trouver comment l’utiliser avec "xmminsortingn.h" .

En outre, existe-t-il une documentation pour "xmminsortingn.h" que vous recommanderiez, plutôt que de regarder dans le fichier d’en-tête lui-même?

Si vous vous trouvez dans l’obligation de faire des opérations horizontales sur les vecteurs, en particulier si elles se trouvent à l’intérieur d’une boucle interne, c’est généralement le signe que vous approchez de la mise en œuvre de votre SIMD. SIMD aime opérer élément par vecteur sur les vecteurs – “verticalement” si vous voulez, pas horizontalement.

En ce qui concerne la documentation, il existe une référence très utile sur intel.com, qui contient tous les opcodes et tous les éléments insortingnsèques, de MMX aux versions SSE en passant par AVX et AVX-512.

Au cas où n’importe qui s’en soucierait et comme les insortingnsèques semblent être la voie à suivre, voici une solution en termes d’insortingnsèques.

 int horizontal_max_Vec4i(__m128i x) { __m128i max1 = _mm_shuffle_epi32(x, _MM_SHUFFLE(0,0,3,2)); __m128i max2 = _mm_max_epi32(x,max1); __m128i max3 = _mm_shuffle_epi32(max2, _MM_SHUFFLE(0,0,0,1)); __m128i max4 = _mm_max_epi32(max2,max3); return _mm_cvtsi128_si32(max4); } 

Je ne sais pas si c’est mieux que ça:

 int horizontal_max_Vec4i(__m128i x) { int result[4] __atsortingbute__((aligned(16))) = {0}; _mm_store_si128((__m128i *) result, x); return max(max(max(result[0], result[1]), result[2]), result[3]); } 

Selon cette page , il n’y a pas de maximum horizontal et vous devez tester les éléments verticalement:

 movhlps xmm1,xmm0 ; Move top two floats to lower part of xmm1 maxps xmm0,xmm1 ; Get maximum of the two sets of floats pshufd xmm1,xmm0,$55 ; Move second float to lower part of xmm1 maxps xmm0,xmm1 ; Get minimum of the two remaining floats 

Inversement, obtenir le minimum:

 movhlps xmm1,xmm0 minps xmm0,xmm1 pshufd xmm1,xmm0,$55 minps xmm0,xmm1 

Il n’y a pas d’opcode Maximum horizontal dans SSE (au moins jusqu’au point où j’ai arrêté de garder une trace des nouvelles instructions SSE).

Donc, vous êtes coincé en train de remuer. Vous vous retrouvez avec …

 movhlps %xmm0, %xmm1 # Move top two floats to lower part of %xmm1 maxps %xmm1, %xmm0 # Get minimum of sets of two floats pshufd $0x55, %xmm0, %xmm1 # Move second float to lower part of %xmm1 maxps %xmm1, %xmm0 # Get minimum of all four floats originally in %xmm0 

http://locklessinc.com/articles/instruction_wishlist/

MSDN a documenté les mappages de fonctions insortingnsèques et de macros

http://msdn.microsoft.com/en-us/library/t467de55.aspx