¿Cómo se multiplican cuatro enteros de 32 bits por otros 4 enteros? No encontré ninguna instrucción que pueda hacerlo.multiplicación SSE de 4 enteros de 32 bits
Respuesta
Si necesita firmaron 32x32 bits multiplicación entera entonces el siguiente ejemplo en software.intel.com parece que debería hacer lo que quiera:
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 */
}
Es posible que desee tener dos compilaciones - uno para CPUs viejas y una para CPU recientes, en cuyo caso podría hacer lo siguiente:
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, de SSE 4.1, hace eso.
La descripción es un poco engañosa, habla sobre la multiplicación con signo, pero como solo almacena los 32 bits inferiores, es realmente una instrucción de signo indiferente que puede usarse para ambos, al igual que IMUL
.
Thanks. Pero, ¿hay alguna manera de usar solo las instrucciones de SSE 2? – Yury
'_mm_mullo_epi32' si prefiere utilizar elementos intrínsecos que el conjunto sin procesar –
@Leviathan Sí, pero necesita varias instrucciones. Dependiendo de la arquitectura, cuatro 'imul' son posiblemente más rápidos y simples – hirschhornsalz
- 1. multiplicación SSE 16 x uint8_t
- 2. enteros de 32 bits sin signo en Javascript
- 3. Emulación SSE optimizada de enteros de 64 bits
- 4. Multiplicación rápida de enteros muy grandes
- 5. Conversión de entero de 32 bits a 4 caracteres
- 6. contador SSE de 128 bits
- 7. ¿Por qué usar enteros menores que 32 bits?
- 8. multiplicación de enteros rápida/rápida en ruby?
- 9. Diferencia entre "Mi Mac de 32 bits" y "Mi Mac de 64 bits" en Xcode 4?
- 10. 64 bits por división de 32 bits
- 11. Rendimiento de punto flotante de 32 bits frente a de 64 bits
- 12. ¿Cómo clasificaría 1 millón de enteros de 32 bits en 2MB de RAM?
- 13. ¿Hay alguna manera de multiplicar correctamente dos enteros de 32 bits en Javascript?
- 14. Entender el algoritmo de Schönhage-Strassen (multiplicación de enteros grandes)
- 15. En la multiplicación de enteros, desbordamiento y pérdida de información
- 16. Arrays de JavaScript: ¿números enteros de 64 bits?
- 17. ¿Qué tiene de malo cambiar 32 bits de una variable de 32 bits?
- 18. ¿Alguna razón para usar enteros de 32 bits para operaciones comunes en la CPU de 64 bits?
- 19. implementación larga larga en máquina de 32 bits
- 20. Compilación de 32 bits con llvm-gcc de 64 bits
- 21. Conversión de punto flotante de 32 bits a 16 bits
- 22. Lectura en 16 bits de un registro de 32 bits
- 23. Determinación de Windows de 64 bits frente a 32 bits
- 24. Agregar números de 64 bits con aritmética de 32 bits
- 25. Registros de 64 bits en ventanas de 32 bits
- 26. División de 64/32 bits en un procesador con división de 32/16 bits
- 27. Asignar un flotador de 32 bits a un entero de 32 bits
- 28. uint es de 32 bits, sin importar si el sistema es de 32 o 64 bits?
- 29. individual de 32 bits con 32 MSI/controladores de 64 bits
- 30. ¿Puede un programa de 32 bits usar más de 4 GB de memoria en un sistema operativo de 64 bits?
Buena respuesta. Es curioso que hayas hecho exactamente el mismo error tipográfico que tuve una vez en mi código: debería ser _____SSE4_1_____ (sin guiones bajos entre E y 4). Molesto, porque no te das cuenta fácilmente - el programa se ejecuta perfecto siempre que la ruta del código alternativo sea correcta – hirschhornsalz
@drhirsch: gracias por arreglar eso - en código real tiendo a usar '__MNI__',' __SNI__', etc. - principalmente por razones históricas, pero también es menos propenso a errores simples como el anterior. –
¡Impresionante, gracias! Ahora, si hubiera un truco similar para reemplazar '_mm_insert_epi32' en una CPU con SSE2 solamente ... –