Reduje un problema en mi código que crea 260 bytes adicionales de uso de RAM estática:
BYTE Height = 150;
BYTE sampleLevel(BYTE ADCchan,BYTE averages)
{
float samp;
//int samp;
BYTE level;
samp = avgSampleADC(ADCchan,averages);
level = 100-(samp*100/Height);
return level;
}
BYTE
aquí hay un tipo uint8_t. Si hago un comentario float samp
y lo convierto en un int
tipo, el uso de RAM estática vuelve a ser lo que esperaba. Supongo que esto tiene algo que ver con la operación matemática level = 100-(samp*100/Height);
, pero no sé qué es. ¿Qué está sucediendo para crear tal comportamiento?
Para muchas funciones matemáticas, existe una compensación entre el uso de RAM y la velocidad. Supongo que la biblioteca de coma flotante AVR estará optimizada para la velocidad.
Bitrex tiene razón: intente evitar el punto flotante en los microcontroladores a menos que sea absolutamente necesario. ¿Realmente necesita punto flotante, o lo hará el punto fijo? Puede emular el punto fijo colocando un punto decimal virtual en algún lugar de un int.
En tu ejemplo multiplicas samp
por
. El resultado, almacenado en un BYTE
no tendrá una precisión muy alta. En un caso como ese, puede elegir un factor de escala que sea más fácil de calcular que el
. Encuentre una aproximación de la forma
. En este caso
~ 0.668 es una buena opción, con un error de solo 0.2%. Y es mucho más fácil de calcular: multiplique por 171 y desplace 8 bits a la derecha. No se necesita división.
¿Estás usando flotadores en algún otro lugar? Si no, el flotante aquí puede estar extrayendo toda la biblioteca de punto flotante, que puede estar asignando memoria para sí mismo. Muy rara vez hay necesidad de usar punto flotante en aplicaciones integradas, ya que no necesita el amplio rango de PF para procesar el rango limitado de valores de entradas del mundo real como ADC, etc. Recuerde que FP le brinda rango, no precisión. Casi siempre es mucho más pequeño y rápido usar punto fijo, y un valor de punto fijo siempre será más preciso que uno de FP del mismo tamaño.
Lo que probablemente estés viendo es lo que se conoce como Promoción Variable .
Al realizar cualquier operación matemática que involucre múltiples tipos de variables, todas las variables dentro de la fórmula se promocionan a tipos de la mayor precisión (flotante en su caso). Por lo tanto, la variable Altura se copiará en una variable flotante temporal antes de que se realice la operación.
Esto solo representará una pequeña parte del aumento del uso de la memoria.
El resto probablemente se deba a la inclusión de toda la biblioteca de punto flotante en el sistema. Sin conocer el funcionamiento interno de la biblioteca de coma flotante del AVR, no puedo decir qué haría con dicha memoria (la mayoría de la memoria utilizada sería la memoria del programa y no la RAM).
Como ha mencionado stevenvh , hay formas mucho más eficientes de realizar este tipo de operaciones que no utilizan la biblioteca de punto flotante en absoluto, y el punto flotante, como se ha mencionado correctamente en otra parte, no es realmente lo que busca aquí, ya que tiene un factor de error inherente. Lo que realmente desea es el doble , no el flotador , ya que esta es una precisión fija con una mejor precisión que el flotador; sin embargo, aún no es tan eficiente como hacer matemáticas enteras al 100%.
He visto una explosión en la utilización de la memoria flash en avr-gcc si no usa el -lm
indicador en el enlazador para vincular las rutinas de emulación de coma flotante optimizadas avr a través de la biblioteca matemática. Probablemente también debería tener la eliminación de funciones no utilizadas (-ffunction-sections)
configurada en los indicadores del compilador y -Wl,-gc-sections
configurada en los indicadores del vinculador si le importa minimizar la huella de memoria. Tenga en cuenta los guiones iniciales en todas las banderas.
Como referencia, las preguntas frecuentes del manual avr-gcc hablan explícitamente de esto. Aquí también hay otra buena referencia para las optimizaciones que puede aplicar en avr-gcc.
Habiendo dicho todo lo anterior, ahorrará la mayor cantidad de memoria simplemente no usando variables de punto flotante en su código, si puede formular su problema estrictamente en números enteros o matemáticas de punto fijo , ¡debería hacerlo!
mattyz