2017-01-09 1 views
3

Comment diviser 16 entiers de 8 bits par 4 (ou les déplacer 2 vers la droite) en utilisant les intrinsèques SSE?Diviser les entiers de 8 bits par 4 (ou décalage) en utilisant SSE

+3

Je pense que juste en spécifiant le bon -march ou -mtune le fait arriver automagically: https://godbolt.org/g/jxGyFd –

+1

Tout d'abord cet outil est génial pour les pages Q & A comme StackOverflow. Je l'ai immédiatement mis en signet. Et pour le vrai contenu de la réponse, merci de jeter un coup d'oeil à l'assemblage, si le compilateur le fait automatiquement dans certains cas je devrais pouvoir le lire hors de l'assemblée de toute façon. – miho

+0

@RichardHodges Je trouve ce code assez décevant en fait, Clang fait un bon travail. – harold

Répondre

4

Malheureusement, il n'y a pas d'instructions de décalage SSE pour les éléments 8 bits. Si les éléments sont 8 bits non signé alors vous pouvez utiliser un décalage de 16 bits et masquer les bits élevés non désirés, par ex.

v = _mm_srli_epi16(v, 2); 
v = _mm_and_si128(v, _mm_set1_epi8(0x3f)); 

Pour 8 bits signé éléments, il est un peu fiddlier, mais toujours possible, bien qu'il puisse être plus facile de déballer à 16 bits, faire les quarts de travail, emballer puis de nouveau à 8 bits.

+1

Merci, juste résolu moi-même en écrivant une macro qui fausse epi8: '' '#define _mm_srli_epi8 (mm, Imm) _mm_et_si128 (_mm_set1_epi8 (0xFF >> Imm), _mm_srli_epi32 (mm, Imm))' '' – miho

+1

@miho: Notez qu'il n'y a pas vraiment d'avantages à écrire ceci en tant que macro au lieu d'une fonction en ligne ici. –

+1

@DietrichEpp: en fait certains compilateurs se plaignent si le 'Imm' dans' _mm_srli_epi32' n'est pas une constante littérale (en particulier dans les builds de débogage), ce qui peut poser un problème avec les fonctions inline, même si vous devriez avoir des versions actuelles/gcc , clang, ICC. –