es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿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?

Tags:  , , ,

Answer

  1. Avatar for 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 utilizando pmovsxbd (con signo) o pmovzxbd (sin signo), multiplicarlos utilizando pmulld y luego sumar los resultados utilizando la adición horizontal (phaddd). Aquí tienes un ejemplo de implementación:

    MultiplyAndSum PROC
    
        ; cargar los bytes en los registros XMM
        movdqu xmm0, FIRST
        movdqu xmm1, SECOND
    
        ; expandir a valores con signo de 32 bits
        pmovsxbd xmm0, xmm0
        pmovsxbd xmm1, xmm1
    
        ; multiplicar los valores de 32 bits correspondientes
        pmulld xmm0, xmm1
    
        ; sumar horizontalmente los resultados
        phaddd xmm0, xmm0
        phaddd xmm0, xmm0
    
        ; mover la suma al registro de retorno
        movd eax, xmm0
    
        ret
    
    MultiplyAndSum ENDP
    

Comments are closed.