Tengo arrays de bytes muy largos que deben agregarse a una matriz de destino de tipo short
(o int
). ¿Existe tal instrucción SSE? O tal vez su conjunto?SSE Instrucciones: Byte + Corto
Respuesta
Necesita descomprimir cada vector de valores de 8 bits en dos vectores de valores de 16 bits y luego agregarlos.
__m128i v = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0);
__m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0)); // vl = { 7, 6, 5, 4, 3, 2, 1, 0 }
__m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0)); // vh = { 15, 14, 13, 12, 11, 10, 9, 8 }
donde v
es un vector de 16 x 8 valores de bit y vl
, vh
son los dos vectores sin envasar de valores de 8 x 16 bits.
Tenga en cuenta que supongo que los valores de 8 bits no están firmados, por lo que al desempaquetar en 16 bits, el byte alto se establece en 0 (es decir, sin extensión de signo).
Si desea sumar muchos de estos vectores y obtener un resultado de 32 bits, entonces un truco útil es usar _mm_madd_epi16
con un multiplicador de 1, p.
__m128i vsuml = _mm_set1_epi32(0);
__m128i vsumh = _mm_set1_epi32(0);
__m128i vsum;
int sum;
for (int i = 0; i < N; i += 16)
{
__m128i v = _mm_load_si128(&x[i]);
__m128i vl = _mm_unpacklo_epi8(v, _mm_set1_epi8(0));
__m128i vh = _mm_unpackhi_epi8(v, _mm_set1_epi8(0));
vsuml = _mm_add_epi32(vsuml, _mm_madd_epi16(vl, _mm_set1_epi16(1)));
vsumh = _mm_add_epi32(vsumh, _mm_madd_epi16(vh, _mm_set1_epi16(1)));
}
// do horizontal sum of 4 partial sums and store in scalar int
vsum = _mm_add_epi32(vsuml, vsumh);
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 8));
vsum = _mm_add_epi32(vsum, _mm_srli_si128(vsum, 4));
sum = _mm_cvtsi128_si32(vsum);
Si necesita inscribirse extender los vectores de bytes en lugar de cero a extender, utilice pmovsxbw
(_mm_cvtepi8_epi16
). A diferencia de las instrucciones para desempaquetar hi/lo, solo puede pmovsx desde la mitad baja/trimestre/octava de un registro src.
Puede pmovsx directamente desde la memoria, aunque los intrínsecos lo hacen realmente torpe. Como el procesamiento aleatorio es más limitado que el rendimiento de carga en la mayoría de las CPU, probablemente sea preferible hacer dos cargas + pmovsx que hacer una carga + tres mezclas.
- 1. Donde las instrucciones SSE superan las instrucciones normales
- 2. Uso de las instrucciones de SSE
- 3. Convertir corto a byte [] en Java
- 4. Uso de instrucciones SSE con gcc sin ensamblaje en línea
- 5. retorno registro SSE con SSE discapacitados
- 6. ¿Cómo usan los compiladores modernos las instrucciones de mmx/3dnow/sse?
- 7. Conciso instrucciones de instrucción SSE y MMX con latencias y rendimiento
- 8. ¿Cómo habilito el conjunto de instrucciones SSE/SSE2 en Visual Studio 2008 (usando CMake)?
- 9. Instrucciones de SSE para agregar todos los elementos de una matriz
- 10. GCC SSE código de optimización
- 11. ¿Alguien que usa tipos primitivos de corto y byte en aplicaciones reales?
- 12. int, el rendimiento a corto byte en la espalda con espalda para-bucles
- 13. ¿Por qué Scala define un operador "+ =" para los tipos Corto y Byte?
- 14. Cargar flotantes constantes en los registros SSE
- 15. ¿Qué significa UnsignedSaturate in SSE instruction?
- 16. Complex Mul and Div using sse Instructions
- 17. Java: byte [] a Byte []
- 18. byte + byte = resultado desconocido
- 19. Java - Byte [] a byte []
- 20. C++ SSE SIMD framework
- 21. Comenzando con SSE
- 22. funcionalidad glibc y SSE
- 23. SSE, intrínsecos y alineación
- 24. SSE y Servlet 3.0
- 25. ¿por qué byte + = 1 compilar pero byte = byte + 1 no?
- 26. SSE: recíproco si no es cero
- 27. SSE 4.2 Análisis de archivos CSV
- 28. Qt, GCC, SSE y alineación de pila
- 29. decodificación 68k instrucciones
- 30. Leer byte [] como unsigned short Java
Disculpe mi ignorancia, pero ¿está seguro de que es correcto? Este vsum = _mm_madd_epi16 (vh, _mm_set1_epi16 (1)); borraría el valor anterior de vsum. – Alexandros
@Alexandros: tienes razón, y veo al menos otro error allí también. Creo que debo haber tenido prisa cuando escribí esta respuesta. Arreglaré el código pronto, pero viajaré a presente. –
Gracias Paul, no tienes prisa. Me has ayudado mucho en el pasado, así que siempre que puedas, arréglenlo. ¡¡Ten un buen viaje!! – Alexandros