i’m trying to optimize my code and i’ve noticed something really weird on using the float type.
At the begining of my sketch i have declared float temp_ext;
More down thru my code i have this declaration
/* Legge la temperatura esterna*/
float readTemp()
{
float temp_ext = 0.0; // valore convertito in temperatura (°C)
int val = 0; // valore quantizzato dall'ADC [0..1023]
byte nread = 5; // numero di letture (da 5 a 8)
float somma = 0.0; // somma delle letture
for (int i = 0; i < nread; i++)
{
val = analogRead( LM35_pin ); // legge il dato della tensione sul pin 'LM35_pin'
temp_ext = ( 100.0 * vref * val ) / 1024.0; // lo converte in °C
somma += temp_ext; // aggiunge alla somma delle temperature lette
}
return ( somma / nread ); // ne calcola il valore medio
}
as you can see, i have declared another time float temp_ext assigning a value of 0.0
If i compile my program it tells me i’m using 31.772 byte (98%)
If i remove the word “float” and leave just “temp_ext = 0.0;” (without quotations) and i compile my program will occupy more memory and exactly 31.804 byte (98%)!
When you put the word float in front of it, it creates a new variable called temp_ext that just happens to have the same name as the one you put up at global scope.
The variable inside the function is probably used inside the function instead of the global variable. Because the local variable is used, perhaps the compiler keeps it in registers and does not allocate memory for it. That means that the compiler can do more optimizations for the loop as well. The resulting code is smaller.
It is not strange, it is perfectly normal
Arduino sets the compiler to optimize for size. If the compiler would optimize for speed, the resulting size could be larger instead of smaller with the extra variable inside the function.
By declaring temp_ext as a local variable, the compiler is able to flatten out the loop and remove all of the increment, comparison and branch operations. Essentially, it will turn your code into this
int val = 0;
float somma = 0.0;
val = analogRead( LM35_pin );
somma += ( 100.0 * vref * val ) / 1024.0; //this line is likely to be optimised down to a few instructions
//repeat the last two lines five times over . . .
By declaring temp_ext as global, the compiler might be reluctant to perform these optimisations and this would probably result in greater code size.
This is just a theory and I'm very interested to hear other opinions on this.
Delta_G:
When you put the word float in front of it, it creates a new variable called temp_ext that just happens to have the same name as the one you put up at global scope.
Right, the one inside the function is different from the one outside the function. Changes made to the one inside the function won't affect the global one. They might as well have different names. If you want to use the global one in the function, then remove the word "float" from in front of the one in the function.
Delta_G:
Right, the one inside the function is different from the one outside the function. Changes made to the one inside the function won't affect the global one. They might as well have different names. If you want to use the global one in the function, then remove the word "float" from in front of the one in the function.
Thanks, that's what i wanted to know.
So when i put float (in this example, could be int or other) in front i'm declaring a new variable in that scope (not a global scope) and that's why my sketch is occupying less memory, because no value has to be kept in mind globally (or atleast not that one) and so it won't use more memory because it's valid only in the scope. Right?
marcomaroso:
Thanks, that's what i wanted to know.
So when i put float (in this example, could be int or other) in front i'm declaring a new variable in that scope (not a global scope) and that's why my sketch is occupying less memory, because no value has to be kept in mind globally (or atleast not that one) and so it won't use more memory because it's valid only in the scope. Right?
No necessarily. The reason why the code is smaller when you declare that variable as local is because the compiler can better optimise the code.
The compiler can do many optimizations and make many different decisions how to optimize. It is hard to predict.
However, you should not use the same name for two different variables anyway. That is bad programming.