¿Méritos relativos del cálculo de punto fijo frente a coma flotante?


9

Tengo un sistema de procesamiento de señal digital que funciona en una máquina rápida x86 con números de coma flotante de doble precisión . Se me ocurrió que realmente no estoy usando el enorme rango dinámico de la representación de coma flotante: todas las cantidades se ajustan fácilmente en el rango ± 32768.

Mi pregunta: ¿es posible que el cambio a cálculos de punto fijo proporcione un beneficio en la precisión numérica (alta prioridad) o el tiempo de cálculo (baja prioridad)?

Por supuesto, la respuesta depende de cuántos bits están disponibles para un cálculo de punto fijo. ¿Cuántos bits de precisión utilizan los sistemas de punto fijo típicos? ¿Es posible hacer cálculos de punto fijo de manera eficiente, con, digamos, 64 bits ( parte entera de 16 bits, parte fraccionaria de 48 bits ) en x86-64?

Siempre pensé que los cálculos de punto fijo se usaban solo en situaciones donde la potencia de la CPU es limitada. ¿Tiene sentido usar cálculos de punto fijo cuando la potencia de la CPU no es una preocupación?


¿Realmente necesita más que las ~ 15 cifras significativas que le da un valor de coma flotante de doble precisión? Si bien las generalizaciones amplias son malas, diría que si observa el conjunto de todos los sistemas DSP de punto fijo, es probable que los enteros de 16 bits sean el formato más común.
Jason R

Respuestas:


7

La precisión numérica de los enteros solo será mejor que la precisión numérica de los flotantes si la resolución entera es mejor. Los dobles tienen 52 bits fraccionarios, por lo que los flotadores de doble precisión tienen una resolución peor que los enteros en torno a , que es mucho mayor que 32768 ( 2 15 ). Entonces, no, la precisión numérica no será mejor si vas a enteros.252215

El segundo problema es la velocidad. La respuesta es: depende del hardware. Si está ejecutando su programa en un procesador de señal digital que tiene múltiples puntos de multiplicación / acumulación de punto fijo, entonces sí, será mucho más rápido en punto fijo. En un chip x86, por otro lado, en realidad probablemente será más lento en punto fijo. Hice exactamente de lo que estás hablando una vez y vi aumentar los tiempos de ejecución.

Después de hacer algunas búsquedas en Internet descubrí que eso es común. La razón es porque tiene un procesador de punto flotante dedicado que no hace nada cuando hace la transición a punto fijo, mientras que el hardware de punto fijo se comparte con la acción regular de punto fijo, como la aritmética de puntero.

Si desea acelerar el procesamiento, la forma de hacerlo es cambiar de flotadores de doble precisión a flotadores de precisión simple. Eso debería producir un aumento significativo en la velocidad. Sin embargo, eso reduciría su precisión numérica.


Quería decir lo que dice esta respuesta cuando escribí la mía. Éste es mejor. Si no me equivoco, también, leí en alguna parte que en algunas computadoras (¿64 bits tal vez?), El tipo de coma flotante del hardware nativo es doble, por lo que el uso de flotadores de precisión simple (cuatro bytes) podría ser más lento. Esto es algo a tener en cuenta, de todos modos.
heltonbiker

Los flotadores de precisión simple tienen mantisae de 23 bits, los dobles tienen 52 bits.
Paul R

Estoy sugiriendo un entero de 16 bits + una fracción de 48 bits como alternativa al punto flotante de doble precisión. Mencioné 32768 para indicar que mis valores encajarán fácilmente en este rango. Dada la restricción a estos valores, creo que Q16.48 proporcionaría una mayor precisión numérica que el punto flotante de doble precisión.
nibot

1
@nibot De acuerdo. Los dobles tendrían una mejor precisión de -16 a +16, y los enteros fraccionarios tendrían mejor precisión en otros lugares hasta -32769 y +32768. No podían, por supuesto, representar nada más allá de eso. También serían más lentos que los dobles. Para mí, el rango limitado y la velocidad lenta serían factores decisivos, pero YMMV.
Jim Clay

6

Los méritos del punto fijo son principalmente en términos de potencia (como cuando tiene la opción de elegir un hardware de procesador, o el procesador es bueno para apagar las unidades funcionales no utilizadas). Esto se debe a que las unidades de punto fijo suelen ser más pequeñas (menos transistores, cables más cortos, menos capacitancia para superar por MAC) para una tecnología determinada y una tasa de emisión de operación, que el punto flotante.

Sin embargo, una gran cantidad de procesadores contemporáneos comunes (servidor, PC e incluso dispositivos móviles) tienen más y más rápidas FPU (especialmente unidades de FP de precisión simple) que los multiplicadores enteros, y la mayor parte de la potencia del sistema no proviene del uso de la FPU, por lo tanto, el uso de -point tendrá pocas o ninguna ventaja para el cómputo DSP típico en estos productos, y probablemente sea una desventaja en términos de rendimiento puro. Usando la tecnología actual, cualquier ventaja para el punto fijo se acumulará principalmente en pequeños productos integrados, como dispositivos del tamaño de un botón.

Sin embargo, también tenga en cuenta las huellas de memoria y caché del procesador. El uso inteligente de tipos de datos más pequeños (int corto y flotante) para ajustar completamente un gran cálculo en la memoria caché de datos puede compensar cualquier ventaja de ancho de banda de FPU puro.


2
+1 por la mención de la importancia de los problemas de caché con respecto al rendimiento. En los procesadores x86 modernos, diseñar su algoritmo teniendo en cuenta el caché puede tener un gran efecto en el rendimiento.
Jason R

5

Prefiera flotantes de precisión individuales a dobles: esto reducirá a la mitad el ancho de banda de memoria, la huella de caché y los requisitos de almacenamiento, y hará que algunas operaciones matemáticas sean más rápidas. También abre la posibilidad de SIMD de 4 vías si se necesita una mayor optimización.

El punto fijo solo vale la pena cuando no tiene una FPU: la mayoría de las CPU x86 modernas tienen dos FPU, por lo que no se gana nada con el uso del punto fijo, y el rendimiento puede ser significativamente peor con el punto fijo. (Tenga en cuenta también que el punto fijo requiere instrucciones adicionales en comparación con el punto flotante para operaciones como la multiplicación).


Me interesa aumentar la precisión numérica, no reducirla.
nibot

¿Cómo ve que el punto fijo mejora la precisión numérica en relación con un doble, que ya tiene 52 bits de precisión y un enorme rango dinámico?
Paul R

Bueno, podría usar un formato de punto fijo con más de 52 bits.
nibot

Dado que aparentemente necesita al menos 16 bits para la parte entera de su representación de punto fijo, esto lo llevará a más de 64 bits, por lo que probablemente esté buscando un formato para el que su CPU ni siquiera tiene instrucciones enteras nativas. En cuyo caso, también podría usar una biblioteca de enteros grandes existente o similar. Sin embargo, la pregunta más importante a responder es: ¿cuánta precisión necesitas realmente ?
Paul R

3

Además de las muy buenas respuestas proporcionadas aquí, vale la pena agregar algunas cosas:

  • Hay situaciones en las que incluso si tiene requisitos muy básicos sobre el rango dinámico de los datos que procesa, aún necesitará una muy buena precisión para algunas de las operaciones realizadas en él, por ejemplo, querrá aplicar un filtro IIR que requiere coeficientes relativamente pequeños; y truncarlos causaría inestabilidades. Tan pronto como su sistema reciba retroalimentación, hay una buena posibilidad de que los problemas de cuantización / truncamiento lo muerdan cuando use un punto fijo: debe tener mucho más cuidado con cosas como la topología de filtro y los esquemas de truncamiento / ahorro de fracciones.
  • A diferencia de muchas arquitecturas DSP / DSC, el x86 no tiene operaciones enteras saturadas (bueno, está allí en SSE, no en código escalar estándar). Esto significa que en caso de desbordamiento, pueden suceder cosas malas: valores que cambian los signos y "ajuste". Debe tener mucho cuidado con los desbordamientos y el rango dinámico, o realizar pruebas de aspersión en los rangos de operandosen todo tu código. Esto puede dañar seriamente el rendimiento. En comparación, el punto flotante es más resistente a estos problemas, porque el amplio rango dinámico le brinda más "margen" y los desbordamientos no conducirán a fallas catastróficas. La mayoría del código de procesamiento de señal de audio que se ejecuta en las computadoras de escritorio está utilizando el rango -1.0 .. 1.0, precisión simple o doble; así que esto da más de cientos de dB de altura libre. He escrito código de procesamiento de señal de audio con ambos enfoques, y cuando uso punto flotante solo hay unos pocos lugares cuando tengo que recortar / saturar explícitamente la señal, generalmente solo al final de la cadena de procesamiento de señal o en lugares donde ocurre la retroalimentación.

1

Algunos puntos a considerar:

  • La mayoría de los procesadores modernos han optimizado el número de coma flotante durante muchos años, e incluso las GPU ya se están utilizando para eso, con mucho éxito;
  • Los cálculos de punto fijo dañan sus datos y pueden causar serios problemas cuando las operaciones aritméticas no están bien condicionadas (es por eso que los números de punto fijo fueron reemplazados por los de punto flotante);
  • Incluso si usa cortos firmados para CONTENER sus datos (muchos registradores de datos usan precisión de 16 bits), los CÁLCULOS deben hacerse en coma flotante y luego convertirse de nuevo en enteros, de lo contrario podría haber artefactos como la cuantización y el alias.

Como última palabra, creo que nuestros datos del mundo real son preciosos y el cálculo numérico ciego de la computadora es un trabajo humilde y servil. La computadora debe ponerse a hacer el trabajo pesado para sus datos y para usted, y no debe ser tratada como si fuera la verdadera estrella en el programa.


No quise decir que usaría cortos de 16 bits para contener mis cantidades, sino algo así como un formato de punto fijo de 64 bits con una parte entera de 16 bits y una parte fraccional de 48 bits. La motivación es que, de todos modos, si no estoy usando la mayoría de los bits de exponente en el formato de coma flotante, ¿mejoraría mi precisión numérica si en cambio usara esos bits para proporcionar dígitos significativos adicionales?
nibot

215

Una cosa más: me parece que StackOverflow (en lugar de DSP.SE, aquí) sería el lugar ideal para obtener razones más profundas sobre los pros y los contras de un formato sobre el otro.
heltonbiker
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.