¿Existe alguna forma de realizar multiplicación de vectores y suma horizontal (producto punto) en elementos de 8 bits con signo?
Tengo el siguiente código en x64 Microsoft Macro Assembler (ejemplo simplificado):
.DATA
First BYTE -4, -3, -2, -1, 0, 1, 2, 3
Second BYTE 1, 2, 3, 4, 5, 6, 7, 8
.CODE
MultiplyAndSum PROC
; mueve First y Second a vectores
; multiplica los elementos correspondientes
; suma los resultados
; devuelve la suma
MultiplyAndSum ENDP
Lo que quiero lograr en este procedimiento es multiplicar los bytes correspondientes de los dos arreglos utilizando SIMD (no importa qué registros se utilicen exactamente), y luego sumar los resultados. Entonces en este caso, quiero hacer:
-4 * 1 + (-3) * 2 + … + 3 * 8 = 24
y devolver 24.
¿Es posible lograr esto utilizando instrucciones vectoriales?
Por lo que he visto, la mayoría de las instrucciones de multiplicación operan en WORDs o DWORDs, ¿hay alguna forma de dividir la multiplicación en fragmentos y operar por ejemplo en WORDs en lugar de BYTEs?
Las instrucciones pmaddwd
, pmullw
o pmulhw
no parecen útiles en este caso. ¿Hay alguna que esté pasando por alto?
davy.ai
Sí, esto es posible utilizando instrucciones vectoriales. Una opción para multiplicar los bytes correspondientes de las dos matrices utilizando SIMD es utilizar la instrucción
pmulld
, que puede operar en valores de 32 bits. Puedes cargar los bytes en dos registros XMM, expandirlos a valores de 32 bits utilizandopmovsxbd
(con signo) opmovzxbd
(sin signo), multiplicarlos utilizandopmulld
y luego sumar los resultados utilizando la adición horizontal (phaddd
). Aquí tienes un ejemplo de implementación: