www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Schlechte Compileroptimierung?


Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

ich benutze in einem Programm öfters mal _delay_ms(). Leider kann man 
damit nur begrenzt lange warten, und zwar 262.14 ms / F_CPU in MHz.

Damit ich auch länger warten kann, habe ich etwas geschrieben wie

#define MAX_DELAY_MS (262 / (F_CPU / 1000000))

static void my_delay_ms(uint16_t ms) {
  while(ms > MAX_DELAY_MS) {
    ms -= MAX_DELAY_MS;
    _delay_ms(MAX_DELAY_MS)
  }
  _delay_ms(ms);
}

Wenn ich nun _delay_ms() mehrmals per Hand aufrufe, ist das Binary ca. 
500 Byte gross. Benutze ich oben genannte Hilfsfunktion, ist es fast 4KB 
gross, also um ganze 3500 Byte größer. Irgendwas läuft da doch schief, 
oder? Hat jemand eine alternative um länger als MAX_DELAY_MS zu warten 
und nicht mehrmals _delay_ms() per Hand aufrufen zu müssen?

Gruss
Flo

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es sollte sich langsam rumgesprochen haben, dass die Delay-Funktionen 
Fliesskommarechnung zur Umrechnung von Zeiten in Takte verwenden. Was 
bei Konstanten kein Problem ist, da macht das der Compiler. Bei 
Variablen hingegen findet diese Umrechnung dann zur Laufzeit statt, 
platz- und zeitraubend.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist dir das hier zu einfach?
static void my_delay_ms(uint16_t ms) {
  while (ms--) {
    _delay_ms(1);
  }
}

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Davon abgesehen können die neueren Versionen auch längere Delays.

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte das Problem auch mal, aber halt nur bei variablen delays. Hast 
du vielleicht woanders noch ein variables drinnen?

Ach ja - Optimierungen (-O2,3 oder -Os) eingeschaltet? Sonst optimiert 
er vll die Fließkommarechnung nicht weg.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Florian wrote:

> ich benutze in einem Programm öfters mal _delay_ms(). Leider kann man
> damit nur begrenzt lange warten, und zwar 262.14 ms / F_CPU in MHz.

Hast du in der Dokumentation auch mal den nächsten Absatz gelesen?

When the user request delay which exceed the maximum possible one,
_delay_ms() provides a decreased resolution functionality. In this mode
_delay_ms() will work with a resolution of 1/10 ms, providing delays up
to 6.5535 seconds (independent from CPU frequency). The user will not be
informed about decreased resolution.

Oder reicht dir eine Auflösung von 1/10 ms nicht?

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich rufe meine Hilfsfunktion nur mit Konstanten als Parameter auf, nicht 
mit Variablen. Der Compiler weiss also bereits zur Compilezeit wie lange 
ich warten will, daher hat es mich etwas gewundert, dass das nicht 
wegoptimiert wird... Danke für die Antworten!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Florian (Gast)

>ich warten will, daher hat es mich etwas gewundert, dass das nicht
>wegoptimiert wird...

Kann er prinzipiell nicht. _delay_ms(ms) kann nicht mal variabel und mal 
fest sein. Geh mal davon aus, dass die Compiler schlauer sind als 90% 
der Programmierer ;-)

MFG
Falk

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Florian wrote:
> daher hat es mich etwas gewundert, dass das nicht
> wegoptimiert wird...

Dazu müsste der Compiler die Schleife durch mehrfachen Aufruf ersetzen. 
Das macht der nicht so ohne weiteres. Daher wird er die Schleife zu 
Laufzeit berechnen und die delay Funktion entsprechend aufrufen 
(vermutlich mit dem Float Parameter).

Autor: Manni (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich verwende grundsätzlich die attached Funktionen:

 void delay_us (uint16_t n);
 void delay_ms (uint16_t m);

Diese sind vom Timing nahezu exakt, mit Ausnahme von 5 > n > 1 bei 
delay_us. Speicherplatz nur 26 Bytes.

Gruß Manni

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.