Comment multiplier quatre entiers de 32 bits par 4 entiers de plus? Je n'ai trouvé aucune instruction qui puisse le faire.Multiplication SSE de 4 entiers de 32 bits
Répondre
Si vous avez besoin signé 32x32 multiplication entier bits alors l'exemple suivant à software.intel.com semble que cela devrait faire ce que vous voulez:
static inline __m128i muly(const __m128i &a, const __m128i &b)
{
__m128i tmp1 = _mm_mul_epu32(a,b); /* mul 2,0*/
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(a,4), _mm_srli_si128(b,4)); /* mul 3,1 */
return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE (0,0,2,0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE (0,0,2,0))); /* shuffle results to [63..0] and pack */
}
Vous pouvez avoir deux builds - un pour les anciens processeurs et un pour les processeurs récents, auquel cas vous pouvez faire ce qui suit:
static inline __m128i muly(const __m128i &a, const __m128i &b)
{
#ifdef __SSE4_1__ // modern CPU - use SSE 4.1
return _mm_mullo_epi32(a, b);
#else // old CPU - use SSE 2
__m128i tmp1 = _mm_mul_epu32(a,b); /* mul 2,0*/
__m128i tmp2 = _mm_mul_epu32(_mm_srli_si128(a,4), _mm_srli_si128(b,4)); /* mul 3,1 */
return _mm_unpacklo_epi32(_mm_shuffle_epi32(tmp1, _MM_SHUFFLE (0,0,2,0)), _mm_shuffle_epi32(tmp2, _MM_SHUFFLE (0,0,2,0))); /* shuffle results to [63..0] and pack */
#endif
}
PMULLD, à partir de SSE 4.1, fait cela.
La description est légèrement trompeuse, elle parle de multiplication signée, mais comme elle ne stocke que les 32bits inférieurs, c'est vraiment une instruction insensible aux signes que vous pouvez utiliser pour les deux, tout comme IMUL
.
Merci. Mais existe-t-il un moyen d'utiliser uniquement des instructions SSE 2? – Yury
'_mm_mullo_epi32' si vous préférez utiliser l'intrinsèque plutôt que l'assemblage brut –
@Leviathan Oui, mais vous avez besoin de plusieurs instructions. Selon l'architecture, quatre 'imul' sont probablement plus rapides et plus simples. – hirschhornsalz
- 1. Deux entiers signés 32 bits Multiplication à l'aide de SSE2
- 2. Trouver max parmi les entiers de 32 bits
- 3. Multiplication pure de bits élevés dans l'assemblage?
- 4. algorithme de multiplier 64 nombres de bits à l'aide de 32 bits entiers non signés
- 5. Mapper les entiers 32 bits en 32 bins, avec 1,2,4. 2^31 entiers consécutifs par casier
- 6. Utilisation de bits sur des entiers 64 bits dans des systèmes 32 bits (pas d'extension php_gpm)
- 7. Nécessité de faire une multiplication 64 bits sur une machine avec des longueurs de 32 bits
- 8. Compteur SSE 128 bits?
- 9. Multiplication parallèle de grands entiers
- 10. Multiplication rapide de très grands entiers
- 11. "Simuler" un entier de 64 bits avec deux entiers de 32 bits
- 12. PHP: combiner deux entiers de 16 bits dans un entier de 32 bits
- 13. Déplacement de bits/transtypage de type en javascript avec des entiers 32 bits non signés?
- 14. 32 bits d'accès et 32 bits Java
- 15. Manière pythonique de parcourir des bits entiers
- 16. Conversion de l'entier 32 bits à 4 caractères
- 17. ARM - détecter si le résultat de la multiplication tient sur 32 bits
- 18. Émulation SSE optimisée d'entiers 64 bits
- 19. Peut-on atteindre une adresse de mémoire qui n'est pas une multiplication de 4 sur 32 bits?
- 20. OU-multiplication sur les grands entiers
- 21. Multiplication des nombres de 16 bits
- 22. Tableau rapide 24 bits -> Conversion de tableau 32 bits?
- 23. Multiplication de deux entiers donnés en binaire
- 24. 32 bits unsigned int php
- 25. Comment utiliser deux entiers 32 bits en tant que 64 bits dans C?
- 26. Comment stocker un entier 64 bits dans deux entiers 32 bits dans Ruby
- 27. Représentation d'une valeur 32 bits non signée avec deux entiers 16 bits non signés
- 28. octet de swap 2 et 4, dans un nombre entier de 32 bits
- 29. Bitmap Android pixels 8 bits au lieu de 32 bits?
- 30. XOR supérieur 32 bits avec 32 bits inférieurs dans un nombre de 64 bits
Bonne réponse. Drôle, vous avez fait exactement la même faute de frappe que j'avais une fois dans mon code: Ça devrait être _____SSE4_1_____ (pas de soulignement entre E et 4). Gênant, parce que vous ne le remarquez pas facilement - le programme fonctionne parfaitement tant que le chemin du code alternatif est correct – hirschhornsalz
@drhirsch: merci de corriger cela - en code réel j'ai tendance à utiliser '__MNI__',' __SNI__', etc - principalement pour des raisons historiques, mais il est aussi moins sujet à de simples erreurs comme celles ci-dessus. –
Génial, merci! Maintenant, si seulement il y avait un truc similaire pour remplacer '_mm_insert_epi32' sur un CPU avec SSE2 seulement ... –