19 votos

¿Se aplica la regla general "Evitar el uso de coma flotante" a un microcontrolador con una unidad de coma flotante (FPU)?

Como regla general, intento evitar el uso de coma flotante en el código de mis sistemas embebidos.

Las variables de coma flotante son:

  • Computación intensiva
  • No atómico (puede causar problemas en una aplicación RTOS o con interrupciones)
  • Su precisión puede provocar comportamientos no evidentes (problema de comparación de flotadores).

Pero ¿qué pasa con un microcontrolador con un unidad de coma flotante (como el STM32F4)?

¿Siguen siendo válidas esas preocupaciones? ¿Seguiría desaconsejando el uso de coma flotante?

24voto

dahulius Puntos 11

Debes recordar que las FPUs de estos microcontroladores suelen ser FPUs de precisión simple. El punto flotante de precisión simple tiene sólo una mantisa de 24 bits (con el MSB oculto) por lo que puede obtener una mejor precisión de los enteros de 32 bits en algunos casos.

He trabajado con aritmética de coma fija y, en situaciones en las que los datos tienen un rango dinámico limitado, se puede conseguir la misma precisión que con coma flotante de precisión única utilizando coma fija de 32 bits con una mejora de un orden de magnitud en el tiempo de ejecución. También he visto que el compilador arrastra una buena cantidad de sobrecarga de biblioteca para la FPU.

15voto

Potato Monster Puntos 6

Si compras un procesador con FPU por hardware, no tendrás las mismas preocupaciones sobre precisión*, comportamiento reentrante, etc. Adelante, utilízalos.

Un par de reflexiones:

  • Podrías considerar que el procesador puede apagar la (gran) FPU cuando no se usa, así que comprueba que ejecutar tus rutinas FP te ahorra energía (si te importa eso) respecto a hacerlo por software.

  • Dependiendo de la implementación, la FPU también puede tener registros diferentes a los del núcleo - a veces los compiladores pueden hacer un uso inteligente de estos.

  • No utilices la FPU como muleta para un mal diseño de firmware. Por ejemplo, ¿podrías hacer lo mismo con punto fijo y usar el núcleo normal en su lugar?

(* La FPU debe ajustarse a una implementación estándar determinada, por lo que hay que tener en cuenta las limitaciones derivadas de ello).

12voto

Kate Puntos 11

Algunas de las preocupaciones siguen siendo válidas.

  • La aritmética de coma flotante es intrínsecamente más compleja que la de los números enteros. Pero con una unidad de coma flotante, probablemente no lo notarás más, tal vez unos pocos ciclos de cpu adicionales o un poco más de consumo de energía.
  • Las operaciones son atómicas, por lo que esa preocupación desaparece.
  • el problema de precisión / redondeo / comparación sigue existiendo, exactamente en la misma medida que en el cálculo por software.

Especialmente el último puede causar problemas muy desagradables, y obligarle a escribir código no intuitivo, por ejemplo, siempre comparando contra un rango, nunca probando la igualdad contra un valor fijo.

Y recuerda que un flotador de precisión simple sólo tiene 23 bits de resolución, por lo que es posible que tengas que sustituir un entero de 32 bits por un flotador de doble precisión.

11voto

FCanc Puntos 11

Los cálculos suelen salir bien si se dispone de la FPU, y las compensaciones son fáciles de entender.

Pero cuidado con la salida. Si tienes algo parecido a la librería C, te sorprendería la complejidad inherente a printf("%0.6g", x); He visto bibliotecas que utilizaban malloc() en printf() y eso no es el tipo de cosa que te gustaría en un microcontrolador.

6voto

Ron Beyer Puntos 108

Honestamente este es un tipo de micro-optimización que deberías hacer sólo después de tienes una base de código completamente funcional. Algunos MCU también tienen problemas con la división, incluso con números enteros. Así que hacer algo como "multiplicar fp por 100, hacer alguna manipulación, dividir por 100" puede tomar mucho más tiempo que sólo manipular el flotador.

Aquí es donde entra en juego la elaboración de perfiles, hay que elegir las batallas, no hay una única respuesta. Una vez que tengas una base de código operativa, podrás identificar los cuellos de botella y optimizar de forma selectiva. Evitar algo de forma generalizada conduce a microoptimizaciones que llevan más tiempo de codificación del que realmente ahorran. Optimizar flotadores de una rutina de baja prioridad que se ejecuta una vez por hora es inútil, mientras que optimizar flotadores para una tarea pesada es útil.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X