
En informática , los números subnormales son el subconjunto de números desnormalizados (a veces llamados denormales ) que llenan el hueco de desbordamiento negativo alrededor de cero en la aritmética de punto flotante . Cualquier número distinto de cero con una magnitud menor que el número normal positivo más pequeño es subnormal , mientras que denormal también puede referirse a números fuera de ese rango. [ a ]
Terminología
En algunos documentos antiguos (especialmente en documentos de estándares como la versión inicial de IEEE 754 (1985) y la primera versión estándar del lenguaje C (1989) ), el término "denormal" se utiliza para referirse exclusivamente a números subnormales. Este uso persiste en varios documentos de estándares, sobre todo al hablar de hardware incapaz de representar otros números desnormalizados, pero en este análisis se utiliza el término "subnormal" de acuerdo con la revisión de 2008 de IEEE 754. En conversaciones informales, los términos subnormal y denormal se suelen usar indistintamente, en parte porque no existen números binarios IEEE desnormalizados fuera del rango subnormal.
El término «número» se usa de forma bastante imprecisa para describir una secuencia particular de dígitos, en lugar de una abstracción matemática; consulte Aritmética de punto flotante para obtener más detalles sobre cómo se relacionan los números reales con las representaciones de punto flotante. Se puede usar «representación» en lugar de «número» cuando se requiere mayor claridad.
Definición
Los números reales matemáticos pueden aproximarse mediante múltiples representaciones de punto flotante. Una representación se define como normal , y otras se definen como subnormales , denormales o no normales según su relación con la normal .
En un valor de punto flotante normal , no hay ceros iniciales en la mantisa (también llamada comúnmente mantisa); en cambio, los ceros iniciales se eliminan ajustando el exponente (por ejemplo, el número 0.0123 se escribiría como1,23 × 10 −2 ). Por el contrario, un valor de punto flotante desnormalizado tiene una mantisa con un dígito inicial de cero. De estos, los números subnormales representan valores que, si se normalizaran, tendrían exponentes inferiores al exponente representable más pequeño (el exponente tiene un rango limitado).
La mantisa (o significando) de un número de punto flotante IEEE es la parte de un número de punto flotante que representa los dígitos significativos . Para un número normalizado positivo, se puede representar como m 0 . m 1 m 2 m 3 ... m p −2 m p −1 (donde m representa un dígito significativo y p es la precisión) con m 0 distinto de cero . Nótese que para una base binaria , el dígito binario principal siempre es 1. En un número subnormal, dado que el exponente es el menor que puede ser, cero es el dígito significativo principal (0. m 1 m 2 m 3 ... m p −2 m p −1 ), lo que permite la representación de números más cercanos a cero que el número normal más pequeño. Un número de punto flotante puede reconocerse como subnormal cuando su exponente tiene el menor valor posible.
Al rellenar el hueco de desbordamiento de esta manera, se pierden dígitos significativos, pero no tan abruptamente como cuando se utiliza el método de vaciado a cero en caso de desbordamiento (que descarta todos los dígitos significativos al alcanzar dicho desbordamiento). Por lo tanto, la generación de un número subnormal a veces se denomina desbordamiento gradual, ya que permite que un cálculo pierda precisión lentamente cuando el resultado es pequeño.
En la norma IEEE 754-2008 , los números subnormales se admiten tanto en formato binario como decimal. En los formatos de intercambio binario, los números subnormales se codifican con un exponente sesgado de 0, pero se interpretan con el valor del exponente mínimo permitido, que es uno mayor (es decir, como si se codificaran como 1). En los formatos de intercambio decimal, no requieren una codificación especial, ya que el formato admite directamente números no normalizados.
Matemáticamente hablando, los números de coma flotante normalizados de un signo determinado están espaciados aproximadamente de forma logarítmica , por lo que ningún número de coma flotante normal de tamaño finito puede incluir el cero . Los números de coma flotante subnormales son un conjunto de valores espaciados linealmente, que abarcan el intervalo entre los números de coma flotante normales negativos y positivos.
Fondo
Los números subnormales garantizan que la suma y la resta de números de coma flotante nunca produzcan un desbordamiento negativo; dos números de coma flotante cercanos siempre tienen una diferencia representable distinta de cero. Sin un desbordamiento negativo gradual, la resta a − b puede producir un desbordamiento negativo y dar como resultado cero, aunque los valores no sean iguales. Esto, a su vez, puede provocar errores de división por cero que no se producen cuando se utiliza un desbordamiento negativo gradual. [ 1 ]
Los números subnormales se implementaron en el Intel 8087 mientras se redactaba el estándar IEEE 754. Fueron, con diferencia, la característica más controvertida de la propuesta de formato KCS que finalmente se adoptó, [ 2 ] pero esta implementación demostró que los números subnormales podían admitirse en una implementación práctica. Algunas implementaciones de unidades de punto flotante no admiten directamente los números subnormales en hardware, sino que recurren a algún tipo de soporte de software. Si bien esto puede ser transparente para el usuario, puede provocar que los cálculos que producen o consumen números subnormales sean mucho más lentos que los cálculos similares con números normales.
IEEE
En los formatos de punto flotante binario IEEE , los números subnormales se representan mediante un campo de exponente cero con un campo de mantisa distinto de cero. [ 3 ] En este estándar, la existencia de números subnormales permite las representaciones de algunos valores distintos de cero con valor absoluto deapara binary32 y desdeapara binary64 .
No existen otros números desnormalizados en los formatos binarios de punto flotante IEEE, pero sí existen en otros formatos, incluidos los formatos decimales de punto flotante IEEE.
Problemas de rendimiento
Algunos sistemas manejan valores subnormales en hardware, de la misma manera que los valores normales. Otros dejan el manejo de valores subnormales al software del sistema ("asistencia"), manejando solo valores normales y cero en hardware. El manejo de valores subnormales en software siempre conlleva una disminución significativa del rendimiento. Cuando los valores subnormales se calculan completamente en hardware, existen técnicas de implementación que permiten su procesamiento a velocidades comparables a las de los números normales. [ 4 ] Sin embargo, la velocidad de cálculo sigue estando significativamente reducida en muchos procesadores x86 modernos; en casos extremos, las instrucciones que involucran operandos subnormales pueden tomar hasta 100 ciclos de reloj adicionales, lo que hace que las instrucciones más rápidas se ejecuten hasta seis veces más lento. [ 5 ] [ 6 ]
Esta diferencia de velocidad puede suponer un riesgo para la seguridad. Los investigadores demostraron que proporciona un canal lateral de sincronización que permite a un sitio web malicioso extraer el contenido de una página de otro sitio dentro de un navegador web. [ 7 ]
Algunas aplicaciones necesitan incluir código para evitar números subnormales, ya sea para mantener la precisión o para evitar la penalización de rendimiento en algunos procesadores. Por ejemplo, en aplicaciones de procesamiento de audio , los valores subnormales suelen representar una señal tan débil que está fuera del rango de audición humana. Debido a esto, una medida común para evitar subnormales en procesadores donde habría una penalización de rendimiento es cortar la señal a cero una vez que alcanza niveles subnormales o mezclarla con una señal de ruido extremadamente débil. [ 8 ] Otros métodos para prevenir números subnormales incluyen agregar un desplazamiento de CC , cuantificar números, agregar una señal de Nyquist, etc. [ 9 ] Desde la extensión de procesador SSE2 , Intel ha proporcionado dicha funcionalidad en el hardware de la CPU, que redondea los números subnormales a cero. [ 10 ]
Deshabilitar los números de coma flotante subnormales a nivel de código
Intel SSE
Los compiladores C y Fortran de Intel habilitan las banderas DAZ(denormals-are-zero) y FTZ(flush-to-zero) para SSE de forma predeterminada para niveles de optimización superiores a -O0. [ 11 ] El efecto de DAZes tratar los argumentos de entrada subnormales para operaciones de punto flotante como cero, y el efecto de FTZes devolver cero en lugar de un float subnormal para operaciones que darían como resultado un float subnormal, incluso si los argumentos de entrada no son subnormales en sí mismos. Clang y GCC tienen estados predeterminados variables dependiendo de la plataforma y el nivel de optimización.
A continuación se muestra un método no compatible con C99 para habilitar las banderas DAZy FTZen objetivos que admiten SSE, pero no cuenta con un amplio soporte. Se sabe que funciona en Mac OS X desde al menos 2006. [ 12 ]
#include <fenv.h> #pragma STDC FENV_ACCESS ON // Establece DAZ y FTZ, sobrescribiendo otras configuraciones de CSR. fesetenv ( FE_DFL_DISABLE_SSE_DENORMS_ENV ); // fesetenv(FE_DFL_ENV) // Deshabilita ambos, sobrescribiendo otras configuraciones de CSR.Para otras plataformas x86-SSE donde la biblioteca C aún no ha implementado esta bandera, lo siguiente puede funcionar: [ 13 ]
#include <xmmintrin.h> _mm_setcsr ( _mm_getcsr () | 0x0040 ); // DAZ _mm_setcsr ( _mm_getcsr () | 0x8000 ); // FTZ _mm_setcsr ( _mm_getcsr () | 0x8040 ); // Ambos _mm_setcsr ( _mm_getcsr () & ~ 0x8040 ); // Deshabilitar ambosLas macros _MM_SET_DENORMALS_ZERO_MODEy _MM_SET_FLUSH_ZERO_MODEenvuelven una interfaz más legible para el código anterior. [ 14 ]
// Para habilitar DAZ #include <pmmintrin.h> _MM_SET_DENORMALS_ZERO_MODE ( _MM_DENORMALS_ZERO_ON ); // Para habilitar FTZ #include <xmmintrin.h> _MM_SET_FLUSH_ZERO_MODE ( _MM_FLUSH_ZERO_ON );La mayoría de los compiladores ya proporcionan la macro anterior por defecto; de lo contrario, se puede utilizar el siguiente fragmento de código (la definición de FTZ es análoga):
#define _MM_DENORMALS_ZERO_MASK 0x0040 #define _MM_DENORMALS_ZERO_ON 0x0040 #define _MM_DENORMALS_ZERO_OFF 0x0000#define _MM_SET_DENORMALS_ZERO_MODE(modo) _mm_setcsr((_mm_getcsr() & ~_MM_DENORMALS_ZERO_MASK) | (modo)) #define _MM_GET_DENORMALS_ZERO_MODE() (_mm_getcsr() & _MM_DENORMALS_ZERO_MASK)El comportamiento de desnormalización predeterminado viene determinado por la ABI , por lo que un software que se comporte correctamente debería guardar y restaurar el modo de desnormalización antes de volver al código que realiza la llamada o al código que la realiza en otras bibliotecas.
BRAZO
En las arquitecturas ARM, el manejo de números de punto flotante subnormales depende de la configuración de la unidad de punto flotante, con algunas implementaciones que admiten un desbordamiento gradual en el hardware, mientras que otras recurren por defecto al comportamiento de vaciado a cero por razones de rendimiento. [ 15 ]
La FPU AArch32 NEON (SIMD) siempre usa un modo de vaciado a cero, [ 16 ] que es el mismo que FTZ + DAZ. Para la FPU escalar y en la SIMD AArch64, el comportamiento de vaciado a cero es opcional y está controlado por el FZbit del registro de control : FPSCR en Arm32 y FPCR en AArch64. [ 17 ]
Una forma de hacerlo puede ser:
#if defined(__arm64__) || defined(__aarch64__) uint64_t fpcr ; asm ( "mrs %0, fpcr" : "=r" ( fpcr )); //Cargar el registro FPCR asm ( "msr fpcr, %0" :: "r" ( fpcr | ( 1 << 24 ) )); //Establecer el bit 24 (FTZ) a 1 #endifAlgunos procesadores ARM tienen manejo de hardware para números subnormales.
Véase también
Notas
- ↑ El sistema de punto flotante binario IEEE solo tiene números desnormalizados subnormales, porque todos los números que no son subnormales tienen un 1 inicial implícito en la mantisa, lo que garantiza que sean normales . Todas las codificaciones que utilizan más de un bit por dígito tendrán algunos valores desnormalizados fuera de cualquier rango subnormal; por ejemplo, todas las codificaciones de punto flotante decimal IEEE tienen 4 bits por dígito, lo que permite que el dígito principal sea 0 para cualquier valor del exponente.
Referencias
- ↑ William Kahan. "Actas de la reunión IEEE 754R, 2002" . Archivado del original el 15 de octubre de 2016. Consultado el 29 de diciembre de 2013 .
- ↑ Severance, Charles (20 de febrero de 1998). "Una entrevista con el Viejo del Punto Flotante" . Entrevistado: William Kahan . Universidad de California, Berkeley.
- ↑ "Números desnormalizados" . Caldera International . Consultado el 11 de octubre de 2023 .(Tenga en cuenta que la documentación de XenuOS utiliza el tipo denormalizado, mientras que IEEE 754 utiliza el tipo subnormalizado ).
- ↑ Schwarz, EM; Schmookler, M.; Son Dao Trong (julio de 2005). "Implementaciones de FPU con números desnormalizados" (PDF) . IEEE Transactions on Computers . 54 (7): 825– 836. doi : 10.1109/TC.2005.118 . S2CID 26470540 .
- ↑ Dooley, Isaac; Kale, Laxmikant (12 de septiembre de 2006). "Cuantificación de la interferencia causada por valores de punto flotante subnormales" (PDF) . Recuperado el 30 de noviembre de 2010 .
- ↑ Fog, Agner. "Tablas de instrucciones: Listas de latencias de instrucciones, rendimientos y desgloses de microoperaciones para CPU Intel, AMD y VIA" (PDF) . Consultado el 25 de enero de 2011 .
- ↑ Andrysco, Marc; Kohlbrenner, David; Mowery, Keaton; Jhala, Ranjit; Lerner, Sorin; Shacham, Hovav. "Sobre el punto flotante subnormal y la sincronización anormal" (PDF) . Consultado el 5 de octubre de 2015 .
- ↑ Serris, John (16 de abril de 2002). "Desnormalización del Pentium 4: picos de CPU en aplicaciones de audio" . Archivado del original el 25 de febrero de 2012. Recuperado el 29 de abril de 2015 .
- ↑ de Soras, Laurent (19 de abril de 2005). "Números desnormalizados en aplicaciones de procesamiento de señales de punto flotante" (PDF) .
- ↑ Casey, Shawn (16 de octubre de 2008). "Asistencias de punto flotante x87 y SSE en IA-32: Flush-To-Zero (FTZ) y Denormals-Are-Zero (DAZ)" . Recuperado el 3 de septiembre de 2010 .
- ↑ "Biblioteca Intel® MPI – Documentación" . Intel.
- ↑ "Re: Problema de rendimiento de la MacBook Pro" . Apple Inc. Archivado del original el 26 de agosto de 2016.
- ↑ "Re: Cambio de estado de punto flotante (anteriormente: rendimiento de double frente a float)" . Apple Inc. Archivado del original el 15 de enero de 2014. Recuperado el 24 de enero de 2013 .
- ↑ "Guía del usuario del compilador C++ para sistemas Linux*" . Intel.
- ↑ "Manual de referencia de la arquitectura Arm: comportamiento de punto flotante" . Arm Ltd.
- ↑ "Documentación – Desarrollador de Arm" . developer.arm.com . Consultado el 20 de julio de 2025 .
- ↑ "Registros Aarch64" . Arm.
Lecturas adicionales
- Eric Schwarz, Martin Schmookler y Son Dao Trong (junio de 2003). «Implementaciones de hardware de números desnormalizados» (PDF) . Actas del 16.º Simposio IEEE sobre Aritmética Computacional (Arith16) . 16.º Simposio IEEE sobre Aritmética Computacional . IEEE Computer Society . págs. 104-111 . ISBN 0-7695-1894-X.
- Véanse también varios artículos en el sitio web de William Kahan.para ver ejemplos de cómo los números subnormales ayudan a mejorar los resultados de los cálculos.
- aritmética informática