Dado que un sistema de 32 bits no puede administrar un número 2 ^ 33 (debido al límite obvio de 32 bits), ¿cómo puede administrar un número de coma flotante de 80 bits ?
Debería requerir "80 bits" ...
Dado que un sistema de 32 bits no puede administrar un número 2 ^ 33 (debido al límite obvio de 32 bits), ¿cómo puede administrar un número de coma flotante de 80 bits ?
Debería requerir "80 bits" ...
Respuestas:
Uno de los significados de una CPU de 32 bits es que sus registros tienen 32 bits de ancho. Esto no significa que no pueda lidiar con, digamos, números de 64 bits, solo que tiene que lidiar primero con la mitad inferior de 32 bits, luego con la mitad superior de 32 bits. (Es por eso que las CPU tienen un indicador de acarreo ). Es más lento que si la CPU pudiera cargar los valores en un registro más amplio de 64 bits, pero aún es posible.
Por lo tanto, el "bitness" de un sistema no limita necesariamente el tamaño de los números con los que puede lidiar un programa, porque siempre puede dividir las operaciones que no encajan en los registros de la CPU en múltiples operaciones. Por lo tanto, hace que las operaciones sean más lentas, consuma más memoria (si tiene que usar la memoria como "bloc de notas") y más difícil de programar, pero las operaciones aún son posibles.
Sin embargo, nada de eso importa, por ejemplo, con procesadores Intel de 32 bits y coma flotante, ya que la parte de coma flotante de la CPU tiene sus propios registros y tienen 80 bits de ancho. (Al principio de la historia del x86, la capacidad de punto flotante era un chip separado, estaba integrado en la CPU a partir de 80486DX).
La respuesta de @ Breakthrough me inspiró a agregar esto.
Los valores de coma flotante, en la medida en que están almacenados en los registros de FPU, funcionan de manera muy diferente a los valores enteros binarios.
Los 80 bits de un valor de coma flotante se dividen entre una mantisa y un exponente (también existe la "base" en los números de coma flotante que siempre es 2). La mantisa contiene los dígitos significativos, y el exponente determina qué tan grandes son esos dígitos significativos. Por lo tanto, no hay "desbordamiento" en otro registro, si su número es demasiado grande para caber en la mantisa, su exponente aumenta y pierde precisión, es decir, cuando lo convierte en un número entero, perderá decimales a la derecha. Por eso se llama coma flotante.
Si su exponente es demasiado grande, entonces tiene un desbordamiento de punto flotante, pero no puede extenderlo fácilmente a otro registro ya que el exponente y la mantisa están unidos.
Podría ser inexacto e incorrecto sobre algo de eso, pero creo que esa es la esencia. (Este artículo de Wikipedia ilustra un poco más brevemente lo anterior).
Está bien que esto funcione de manera totalmente diferente ya que toda la parte de "punto flotante" de la CPU está en su propio mundo: se usan instrucciones especiales de la CPU para acceder a ella y demás. Además, hacia el punto de la pregunta, debido a que es independiente, el bitness de la FPU no está estrechamente acoplado con el bitness de la CPU nativa.
-fomit-frame-pointer
para recuperar ese registro.
32 bits, 64 bits y 128 bits se refieren a la longitud de palabra del procesador, que puede considerarse como el "tipo de datos fundamental". A menudo, este es el número de bits transferidos a / desde la RAM del sistema, y el ancho de los punteros (aunque nada le impide usar software para acceder a más RAM de lo que puede acceder un puntero).
Suponiendo una velocidad de reloj constante (así como que todo lo demás en la arquitectura sea constante), y suponiendo que las lecturas / escrituras de memoria sean de la misma velocidad (asumimos 1 ciclo de reloj aquí, pero esto está lejos del caso en la vida real), puede agregue dos números de 64 bits en un solo ciclo de reloj en una máquina de 64 bits (tres si cuenta recuperar los números de la RAM):
ADDA [NUM1], [NUM2]
STAA [RESULT]
También podemos hacer el mismo cálculo en una máquina de 32 bits ... Sin embargo, en una máquina de 32 bits, necesitamos hacer esto en el software, ya que primero se deben agregar los 32 bits inferiores, compensar el desbordamiento y luego agregar los 64 bits superiores:
ADDA [NUM1_LOWER], [NUM2_LOWER]
STAA [RESULT_LOWER]
CLRA ; I'm assuming the condition flags are not modified by this.
BRNO CMPS ; Branch to CMPS if there was no overflow.
ADDA #1 ; If there was overflow, compensate the value of A.
CMPS ADDA [NUM1_UPPER], [NUM2_UPPER]
STAA [RESULT_UPPER]
Al revisar mi sintaxis de ensamblaje inventada, puede ver fácilmente cómo las operaciones de mayor precisión pueden llevar un tiempo exponencialmente más largo en una máquina de menor longitud de palabra. Esta es la clave real de los procesadores de 64 bits y 128 bits: nos permiten manejar grandes cantidades de bits en una sola operación. Algunas máquinas incluyen instrucciones para agregar otras cantidades con un acarreo (por ejemplo, ADC
en x86), pero el ejemplo anterior tiene en mente valores de precisión arbitrarios.
Ahora, para extender esto a la pregunta, es simple ver cómo podríamos agregar números más grandes que los registros que tenemos disponibles: simplemente dividimos el problema en trozos del tamaño de los registros y trabajamos desde allí. Aunque, como mencionó @MatteoItalia , la pila x87 FPU tiene soporte nativo para cantidades de 80 bits, en sistemas que carecen de este soporte (¡o procesadores que carecen de una unidad de punto flotante por completo!), Los cálculos / operaciones equivalentes deben realizarse en software .
Entonces, para un número de 80 bits, después de agregar cada segmento de 32 bits, también se verificaría el desbordamiento en el bit de 81 puntos y, opcionalmente, cero los bits de orden superior. Estas verificaciones / ceros se realizan automáticamente para ciertas instrucciones x86 y x86-64, donde se especifican los tamaños de operando de origen y destino (aunque estos solo se especifican en potencias de 2 a partir de 1 byte de ancho).
Por supuesto, con los números de coma flotante, uno no puede simplemente realizar la suma binaria ya que la mantisa y los dígitos significativos se empaquetan en forma de desplazamiento. En la ALU en un procesador x86, hay un circuito de hardware para realizar esto para flotadores IEEE de 32 bits y 64 bits; sin embargo , incluso en ausencia de una unidad de punto flotante (FPU), se pueden realizar los mismos cálculos en el software (por ejemplo, mediante el uso de la Biblioteca Científica GNU , que utiliza una FPU cuando se compila en arquitecturas, recurriendo a algoritmos de software si no hay hardware de punto flotante disponible [por ejemplo, para microcontroladores integrados que carecen de FPU]).
Dada suficiente memoria, también se pueden realizar cálculos sobre números de precisión arbitraria (o "infinita" - dentro de límites realistas), utilizando más memoria ya que se requiere más precisión. Existe una implementación de esto en la biblioteca GNU Multiple Precision , que permite una precisión ilimitada (hasta que su RAM esté llena, por supuesto) en operaciones de punto entero, racional y de punto flotante.
La arquitectura de memoria del sistema solo le permite mover 32 bits a la vez, pero eso no impide que use números más grandes.
Piensa en la multiplicación. Es posible que conozca sus tablas de multiplicar hasta 10x10, pero probablemente no tenga problemas para realizar 123x321 en una hoja de papel: simplemente lo divide en muchos problemas pequeños, multiplica los dígitos individuales y se encarga del transporte, etc.
Los procesadores pueden hacer lo mismo. En los "viejos tiempos" tenías procesadores de 8 bits que podían hacer cálculos de coma flotante. Pero eran muuuuuuuuuuy
"32 bits" es realmente una forma de categorizar los procesadores, no una decisión establecida. un procesador de "32 bits" generalmente tiene registros de propósito general de 32 bits para trabajar.
Sin embargo, no hay ningún requisito establecido de que todo en el procesador se realice en 32 bits. Por ejemplo, no era desconocido que una computadora de "32 bits" tuviera un bus de direcciones de 28 bits, porque era más barato fabricar el hardware. Las computadoras de 64 bits a menudo solo tienen un bus de memoria de 40 o 48 bits por la misma razón.
La aritmética de coma flotante es otro lugar donde los tamaños varían. Muchos procesadores de 32 bits admiten números de coma flotante de 64 bits. Lo hicieron almacenando los valores de coma flotante en registros especiales que eran más anchos que los registros de propósito general. Para almacenar uno de estos grandes números de coma flotante en los registros especiales, primero se dividiría el número en dos registros de propósito general, luego se emitiría una instrucción para combinarlos en un flotante en los registros especiales. Una vez en esos registros de coma flotante, los valores se manipularían como flotantes de 64 bits, en lugar de como un par de mitades de 32 bits.
La aritmética de 80 bits que menciona es un caso especial de esto. Si ha trabajado con números de coma flotante, está familiarizado con la imprecisión que surge de los problemas de redondeo de coma flotante. Una solución para el redondeo es tener más bits de precisión, pero luego debe almacenar números más grandes y obligar a los desarrolladores a usar valores de punto flotante inusualmente grandes en la memoria.
La solución de Intel es que los registros de coma flotante son todos de 80 bits, pero las instrucciones para mover valores hacia / desde esos registros funcionan principalmente con números de 64 bits. Siempre que opere completamente dentro de la pila de coma flotante x87 de Intel, todas sus operaciones se realizan con 80 bits de precisión. Si su código necesita extraer uno de esos valores de los registros de coma flotante y almacenarlo en algún lugar, lo trunca a 64 bits.
Moraleja de la historia: las categorizaciones como "32 bits" siempre son más peligrosas cuando profundizas en las cosas.
Una CPU de "32 bits" es aquella en la que la mayoría de los registros de datos son registros de 32 bits, y la mayoría de las instrucciones funcionan con datos en esos registros de 32 bits. También es probable que una CPU de 32 bits transfiera datos hacia y desde la memoria de 32 bits a la vez. La mayoría de los registros de 32 bits no significa que todos los registros sean de 32 bits. La respuesta breve es que una CPU de 32 bits puede tener algunas características que usan otros recuentos de bits, como registros de punto flotante de 80 bits y las instrucciones correspondientes.
Como dijo @spudone en un comentario sobre la respuesta de @ ultrasawblade, la primera CPU x86 en tener operaciones de punto flotante integradas fue la Intel i486 (específicamente la 80486DX pero no la 80486SX), que, según la página 15-1 de los programadores de microprocesadores i486 El Manual de referencia incluye en sus registros numéricos "Ocho registros numéricos de 80 bits direccionables individualmente". El i486 tiene un bus de memoria de 32 bits, por lo que transferir un valor de 80 bits requeriría 3 operaciones de memoria.
El predecesor de la generación 486, el i386, no tenía operaciones integradas de punto flotante. En cambio, tenía soporte para usar un "coprocesador" de coma flotante externo, el 80387. Este coprocesador tenía casi la misma funcionalidad que estaba integrada en el i486, como puede ver en la página 2-1 del Manual de referencia del programador 80387 .
El formato de punto flotante de 80 bits parece haberse originado con el 8087, el coprocesador matemático para los 8086 y 8088. Los 8086 y 8088 eran CPU de 16 bits (con buses de memoria de 16 y 8 bits), y aún podían para utilizar el formato de punto flotante de 80 bits, aprovechando los registros de 80 bits en el coprocesador.