kleine codeänderung, großer unterschied binärcodegröße

hi,

ich sitz grad da und schreib’ den code für meine uhr, und dabei achte ich eigentlich auch auf die ausgabe des compilers zur binären codegröße.
jetzt wollte ich von einem fixen array auf eine berechnung der LED-werte umsteigen und plötzlich ist die codegröße unglaublich gewachsen. also problem eingegrenzt:

wenn ich im setup

float d = pow(hr, 1/2.2)/74;
// fhr = pow(hr, 1/2.2)/74;

verwende, ergibt das eine binäre sketchgröße von 3.990 Bytes.
setze ich die andere zeile aktiv:

// float d = pow(hr, 1/2.2)/74;
fhr = pow(hr, 1/2.2)/74;

wächst die größe auf 5.794 Bytes.

hr und fhr sind global definiert.

byte hr = 255;
float fhr;

weiß dafür jemand eine erklärung?

gruß stefan

uhr4_wo_rtcLib_ueberbl_berechn.ino (2.26 KB)

Ganz einfach: die lokale Variable d wird in der setup()-Routine nicht mehr gebraucht und darum wird vom Compiler der ganze Ausdruck wegoptimiert. Wenn Du hingegen die Zuweisung an die globale Variable machst, muss die pow()-Funktion in den Code integriert werden.

Leider weiss der Compiler nicht, dass setup() nur einmal läuft und zu der Zeit hr so gut wie const ist.

Was bringt denn

fhr = pow(255, 1/2.2)/74;

Das kann zur Compilezeit ausgrechnet werden und avrgcc wird dir sicher die Arbeit abnehmen, diese Konstante zur Initialisierung selbst zu bestimmen.

hi,

Leider weiss der Compiler nicht, dass setup() nur einmal läuft und zu der Zeit hr so gut wie const ist.

also ich hab' ihm sicher schon tausend mal einen sketch hochgeladen, schön langsam sollte er's wissen. aber im ernst: der code kann ja eigentlich nur dann optimiert werden, WENN der compiler weiß, daß setup nur einmal läuft. dann könnte er ja die errechneten werte direkt in den code schreiben und die berechnung weglassen. wäre es anders, muß er ja bei jedem start neu berechnen, und dann wär's auch egal, ob er es nur einmal macht oder mehrmals. hab' ich da einen denkfehler? hr ist keine konstante, sondern soll über eine fernbedienung zu ändern sein. FB grad auf dem weg aus china, deswegen nichts im sketch. es ist auch nicht schlimm mit der codegröße, weil ob ich einen 328er oder einen tiny nehme, macht 1,50 unterschied, aber es verwundert mich eben...

gruß stefan

Ganz einfach: die lokale Variable d wird in der setup()-Routine nicht mehr gebraucht und darum wird vom Compiler der ganze Ausdruck wegoptimiert. Wenn Du hingegen die Zuweisung an die globale Variable machst, muss die pow()-Funktion in den Code integriert werden.

das verstehe ich. aber daß diese eine funktion den code derartig aufbläht, verblüfft mich.

gruß stefan

Eisebaer:
das verstehe ich. aber daß diese eine funktion den code derartig aufbläht, verblüfft mich.

Das ist nicht “eine Funktion”, die den Code so aufbläht, sondern wenn Du auch nur eine einzige Gleitkomma-Rechenoperation in Deinem Programm drin hast, die nicht durch Vorabberechnung zur Kompilierzeit wegoptimiert werden kann, dann wird sämtlicher zusätzlich notwendige Code aus der mathematischen Gleitkomma-Library automatisch mit im Programm eingebunden, z.B. der Code für die “pow” Funktion sowie aller weiteren Funktionen, die von “pow” selbst wieder benutzt werden. Und das bläht den Code auf.

Das fällt Dir nur deshalb nicht auf, weil Arduino die Zeile
#include <math.h>
klammheimlich im Verborgenen in den tatsächlich kompilierten Code einfügt und selbst dann mitkompiliert, wenn Du die Include-Zeile nicht in Deinen Sketch reinschreibst.

hi,

Das fällt Dir nur deshalb nicht auf, weil Arduino die Zeile
#include <math.h>
klammheimlich im Verborgenen in den tatsächlich kompilierten Code einfügt und selbst dann mitkompiliert, wenn Du die Include-Zeile nicht in Deinen Sketch reinschreibst.

klammheimlich also. so ein schlingel…

jetzt verstehe ich die größe. wenn er plötzlich mit gleitkommas umgehen muß.

gruß stefan