Instrucciones 64-bit vs. Instrucciones Avanzadas (SSE, SSE2, SSE3, SSE4, AVX)

Iniciado por Fly_NighT, 4 Marzo 2014, 20:23 PM

0 Miembros y 1 Visitante están viendo este tema.

Fly_NighT

Hola, soy nuevo en el foro, pero afortunadamente no soy tan novato con el tema de ensamblador. Programo por lo general en FASM, y mi procesador (i3-2310M) soporta hasta las instrucciones AVX (no soporta AVX2).

Debo hacer una aplicación que computa operaciones elementales con números enteros (no flotantes) lo suficientemente grandes como para que no entren en un resgistro de 64-bits. Por lo general, estos números enteros me suelen ocupar entre 1024-bits y 128-bits. Para computar las operaciones (suma, resta, multiplicación - NO división) me vi en la necesidad de aplicar las operaciones considerando cada número entero (de 128 a 1024) como un paquete de datos de 64-bits cada uno. Por ejemplo, en la suma, si tengo dos números de 1024-bits, tomo los primeros 64-bits de cada uno y los sumo. Luego vuelvo a hacer lo mismo con el segundo paquete de 64-bits de cada uno, sin olvidar sumarle el carry de la operación anterior, y así sucesivamente.

Mi problema radica en la velocidad de ejecución cuando debo hacer varios cálculos, ya que la cuestión empieza a hacerse lenta. Mironeando por ahí, encontré que las instrucciones SSE (1,2,3 o 4) y las instrucciones AVX permiten manejar registros de tamaño más grandes (128-bit y 256-bit creo, respectivamente, por lo que he leído), lo cuál probablemente haría más rápidas las ejecuciones y los cálculos. El tema es que desconozco cuál es la diferencia entre cada set de instrucciones, y cuáles de todos ellos "podría solventar" mi problema, o si en el peor de los casos, aplicar estas instrucciones empeoraría el rendimiento.

¡Les agradezco de antemano todas las respuestas!

MCKSys Argentina

Hola!

Podrias mirar esto: click

Explica como hacer operaciones de 64 bits usando 32 bits. No es lo que haz preguntado, pero quizas te pueda mostrar otras opciones a la hora de realizar las operaciones.

Fijate que la dinamica para numeros de 128-2048 bits es análoga...  ;)

Saludos!

PD: Te dejo un par de links al respecto:

http://codereview.stackexchange.com/questions/7364/sse2-assembly-optimization-multiply-unsigned-shorts-and-add-the-result
http://en.wikibooks.org/wiki/X86_Assembly/SSE
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


Fly_NighT

Cita de: MCKSys Argentina en  5 Marzo 2014, 03:06 AM
Podrias mirar esto: click

Excelente aporte. Aunque la parte de 64 bits ya la tengo implementada (incluso para operaciones entre números de 1024 bits) es interesante dejar el link. Me habría ahorrado horas de trabajo..

Cita de: MCKSys Argentina en  5 Marzo 2014, 03:06 AM
PD: Te dejo un par de links al respecto:

http://codereview.stackexchange.com/questions/7364/sse2-assembly-optimization-multiply-unsigned-shorts-and-add-the-result
http://en.wikibooks.org/wiki/X86_Assembly/SSE

ESTO resuelve en parte mi problema. El listado de instrucciones para enteros de las instrucciones SIMD (SSE, SSE2, SSE3 y SSE4) por lo menos me permite saber qué instrucciones puedo utilizar. Precisamente ahora estaba revisando el Manual de Desarrolladores de Software de Arquitectura Intel® 64 y IA-32, para ver si encontraba tales instrucciones. Quizá en un par de horas más ya tengo el código que resuelva mi problema para las instrucciones SIMD. Sin embargo, en la página de Wiki no sale nada sobre las instrucciones AVX.  ¿Tienes idea de donde puedo conseguir un listado similar de instrucciones para enteros de AVX? Si consiguiera eso, mi problema quedaría resuelto en un par de horas más. Excelente respuesta, te lo agradezco.

MCKSys Argentina

MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


cpu2

En el primer PDF.

http://software.intel.com/es-es/intel-isa-extensions

Si lo unico qu quieres hacer es una simple suma, con PADDB/PADDW/PADDD/PADD, si no puedes hacerlo de mas maneras.

Un saludo.

Fly_NighT

Cita de: cpu2 en  5 Marzo 2014, 06:24 AM
Si lo unico qu quieres hacer es una simple suma, con PADDB/PADDW/PADDD/PADD, si no puedes hacerlo de mas maneras.

También lo hace la instrucción PADDQ que directamente opera sobre paquetes de 64-bits (quadword). ¿Esas "maneras" de las que hablas incluyen sumas sin "perder" el carry? Las instrucciones PADDB/PADDW/PADDD/PADDQ ejecutan sumas, pero desprecian el carry (overflow) entre cada entero:

" When a result is too large to be represented in the 8/16/32 integer (overflow), the result is wrapped around and the low bits are written to the destination element (that is, the carry is ignored). [...] Note that these instructions can operate on either unsigned or signed (two's complement notation) integers; however, it does not set bits in the EFLAGS register to indicate overflow and/or a carry. To prevent undetected overflow conditions, software must control the ranges of the values operated on."

cpu2

Es que las instrcciones SEEx y AVX no tienen soporte para el carry.

Un saludo.

Fly_NighT

Entonces tendré que implementarlo manualmente, aunque ya no será complicado. Muchas gracias. Mi problema ha sido resuelto. Excelentes respuestas en excelente tiempo. ¡Saludos a todos!

cpu2

Si tendras que implementarlo, piensa que las extensiones SSEx y AVX estan pensadas para hacer calculos independientes en byte, word, doubleword, quad etc...

De hay que tengas instrucciones como padd, pshuf, psll/pslr, pcmepeq, punpckh.

Un saludo