Design: Aritmética con acarreo

Creado en 28 mar. 2017  ·  7Comentarios  ·  Fuente: WebAssembly/design

(Esta es una versión ampliada del problema (https://github.com/WebAssembly/spec/issues/446))

La aritmética de precisión múltiple requiere un manejo especial. Esto está disponible de alguna forma en todas las ISA, pero actualmente no está disponible en webasm.

Básicamente, hay tres formas de hacer esto (me parece), ninguna de las cuales es especialmente aceptable en el contexto del diseño actual:

Opción 1. Agregar un registro de banderas especiales, junto con instrucciones que hagan aritmética con ese registro.

Este es el enfoque tradicional en el hardware convencional.

Recibes instrucciones como

añadir

que agregará dos números y el valor de la bandera de acarreo, y establecerá la bandera de acarreo en el resultado.

Esto no es agradable porque agrega un registro especial.

Opcion 2.
Admite una forma de aritmética de 60 bits con 4 bits para banderas.

Opción 3.
Admite aritmética de varias palabras: la suma toma 3 argumentos y produce 2 salidas.

Este enfoque hará el menor daño a la ISA existente y a la arquitectura de registro. Sin embargo, esto será difícil de mapear al hardware existente de manera eficiente (no todos los ISA de hardware admiten la carga directa del registro de banderas).

Independientemente de cómo se haga, la aritmética de precisión múltiple es bastante importante y muy difícil de emular sin un soporte de hardware simple.

Comentario más útil

¿Ha habido algún progreso en este tema? Se necesita llevar y pedir prestado para implementar la criptografía moderna (por ejemplo, SIDH) de manera eficiente. La suma de números grandes sin ADDC es varios factores más lenta que con. Lo mismo se aplica a la resta y la multiplicación.

Todos 7 comentarios

Me parece que para la opción 3 hay optimizaciones plausibles que harían esto práctico. Supongamos que {i32,i64}.addc toma tres entradas, op2 en la parte superior, op1 debajo, carry en la parte inferior y produce dos salidas, result en la parte superior y carry debajo. En aras del argumento, suponga que el acarreo es siempre del mismo tipo que los otros operandos. Defina addc solo para usar el bit bajo del acarreo y para que el acarreo que queda después de la operación sea cero o uno. Las cosas ahora están razonablemente configuradas para agregar varias palabras, por ejemplo. En un ciclo desenrollado adecuadamente, un compilador JIT/Wasm realmente debería poder ver que es el acarreo lo que se está propagando y generar un buen código. (Y si el bucle no se desenrolla, la sobrecarga del bucle diluirá la extracción/inserción de acarreo de todos modos). Creo que el código libre de bifurcaciones en el peor de los casos para la extracción de acarreo debería ser mov rd, 0; adc rd, 0 ; para la inserción, algo como and rc, 1; add rc, ~0 donde rc es un registro que contiene un valor para ser tratado como un acarreo.

En ARM, consumir un acarreo es independiente de producir un acarreo: ADC consume, ADC.S consume y produce, ADD.S solo produce. ¿Querríamos todas estas variantes? ¿Y el desbordamiento?

(Puede haber una cuarta opción, en la que agregamos una operación de operación y bifurcación según la condición que produce un resultado y se bifurca a una etiqueta o no, por ejemplo, i32.addc op1 op2 carry L se bifurcaría a L en el conjunto de acarreo y falle en carry clear, y de cualquier manera deje un resultado en la pila, pero parece más difícil de usar en general que las tres opciones que sugirió).

¿Hay alguien dispuesto a abanderar esta propuesta? Necesitaríamos la semántica propuesta, la codificación binaria y me gustaría al menos un mínimo de casos de uso y una implementación con números de rendimiento para estos casos de uso (compare el MVP WebAssembly actual, con esta adición propuesta y el código nativo).

En principio, estaría dispuesto a defender esto.
Sin embargo, los cambios personales significan que tengo recursos limitados por lo menos durante los próximos meses.
———
Frank McCabe
Arquitecto de software sénior
Teléfono: 650-740 6673 | Correo electrónico: [email protected] [email protected]
Lógica de inicio | 450 Lambert Ave, Palo Alto, CA 94306 | instartlogic.com http://instartlogic.com/

El 11 de mayo de 2017, a las 10:14 a. m., JF Bastien [email protected] escribió:

¿Hay alguien dispuesto a abanderar esta propuesta? Necesitaríamos la semántica propuesta, la codificación binaria y me gustaría al menos un mínimo de casos de uso y una implementación con números de rendimiento para estos casos de uso (compare el MVP WebAssembly actual, con esta adición propuesta y el código nativo).


Usted está recibiendo esto porque usted fue el autor del hilo.
Responda a este correo electrónico directamente, véalo en GitHub https://github.com/WebAssembly/design/issues/1021#issuecomment-300856161 , o silencie el hilo https://github.com/notifications/unsubscribe-auth/ADfCzd9le4ufXm6DSsArpfXCYsGdV7UIks5r40H5gaJpZM4MrKma .

Probablemente tendré tiempo para dedicarme a esto, aunque no mucho hasta junio más o menos, y luego hasta el otoño. En mi opinión, esta funcionalidad es bastante importante, y creo que el indicador de desbordamiento es tan importante como el indicador de acarreo, aunque con diferentes casos de uso (fixnum de lenguajes dinámicos -> transición bignum).

Discutí esto con algunas personas de Mozilla hoy. En resumen:

  • Probablemente queremos instrucciones dedicadas aquí porque emular el comportamiento será lento y, en general, no queremos hacer coincidencias mágicas de patrones para reconocer la emulación y convertirla en un código de máquina eficiente detrás de escena.
  • Nos preocupamos por carry/borrow y overflow, por supuesto; otras banderas TBD
  • Nos preocupamos por sumar y restar seguro; multiplicar, dividir, rotar (rotar a través de llevar es común, pero ¿es útil para Wasm?) TBD
  • El caso común es que solo nos importa una bandera a la vez y probablemente sea adecuado para cubrir ese caso, no una situación general de "captura de banderas A, B y C".
  • Para carry, es suficiente una instrucción que siempre consuma un carry-in y siempre produzca un carry-out; las variantes que consumen pero no producen o viceversa no son necesarias, y no tenerlas probablemente no afectará la salida de un buen compilador
  • Queremos motivar este trabajo con datos de buenas bibliotecas MP existentes (como Gnu MP); esto podría ser hechos (la biblioteca X tiene/no tiene subrutinas de ensamblador o usa intrínsecos para hacer uso de banderas; usa instrucciones A y B) o datos de rendimiento (la biblioteca Y puede usar subrutinas de ensamblador o emular en C; la diferencia de rendimiento es N% ) o casos de uso (aritmética bignum general, criptografía, cualquier otra cosa que se le ocurra)
  • Es posible que deseemos esperar con la propuesta de instrucciones específicas hasta que comencemos a discutir las instrucciones de producción de valores múltiples en general, por ejemplo, devoluciones de valores múltiples

¿Ha habido algún progreso en este tema? Se necesita llevar y pedir prestado para implementar la criptografía moderna (por ejemplo, SIDH) de manera eficiente. La suma de números grandes sin ADDC es varios factores más lenta que con. Lo mismo se aplica a la resta y la multiplicación.

Creo que al menos estamos esperando que se termine el multivalor para que podamos expresar fácilmente una operación con más de un resultado. El valor múltiple está "casi allí".

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

cretz picture cretz  ·  5Comentarios

dpw picture dpw  ·  3Comentarios

konsoletyper picture konsoletyper  ·  6Comentarios

beriberikix picture beriberikix  ·  7Comentarios

nikhedonia picture nikhedonia  ·  7Comentarios