Forum: Compiler & IDEs Optimierung beurteilen?


von hal (Gast)


Lesenswert?

Hallo,
in der (vermutlich) relativen einfachen Routine:
1
void lcd_string_P(const char *data)
2
{
3
  while(pgm_read_byte(data)!=0)
4
    lcd_data(pgm_read_byte(data++));
5
}
habe ich das Gefühl, dass die Funktion 'pgm_read_byte' nicht unbedingt 
2x innerhalb der Schleife aufgerufen werden muss. Deshalb habe ich 
alternativ die Funktion geändert:
1
void lcd_string_P(const char *data)
2
{
3
  uint8_t i = pgm_read_byte(data);
4
  
5
  while(i!=0)
6
  {
7
    lcd_data(i);
8
    i = pgm_read_byte(++data);
9
  }
10
}
unabhängig ob dies nun offensichtlich dämlich oder clever ist:

Wie kann ich sowas objektiv ermitteln?
(Speicher, Geschwindigkeit, ... was auch immer?)

danke
hal

von dunno.. (Gast)


Lesenswert?

Hi,

läuft der Code auf nem Controller?

Eine Methode für Laufzeitbestimmung ist, sich im Debugger das 
Disassembly anzuschauen, und die Zyklen pro assembler- befehl 
aufzuaddieren, dann kannst dus ziemlich genau bestimmen. Speicher siehst 
du ja sowieso direkt.

Alternativ kannst du auch nen Pin toggeln lassen, zwischen den teilen 
die dich interessieren, und mit nem oskar die zeiten messen.

Gruß
Dunno

von Walter Tarpan (Gast)


Lesenswert?

hal schrieb:
> uint8_t i = pgm_read_byte(data);

Also "i" ist in einer Schleife für einen Temp-Wert SEHR ungünstig. Der 
Variablennamen weckt falsche Erwartungen.

Mit einer do-while - Schleife kannst Du das auch noch etwas "schöner" 
machen:
1
void lcd_string_P(const char *data)
2
{
3
    do {
4
        uint8_t tmp = pgm_read_byte(data);
5
        lcd_data(tmp);
6
    } while (i!=0);
7
}

hal schrieb:
> Wie kann ich sowas objektiv ermitteln?
> (Speicher, Geschwindigkeit, ... was auch immer?)

Zähl die Assembler-Instruktionen oder miß mit einem Oszi. Aber ich 
vermute, die Funktion "lcd_data" wird den Hauptteil der Laufzeit 
ausmachen - da macht Deine "Optimierung" keinen Unterschied.

Viele Grüße
W.T.

von Walter Tarpan (Gast)


Lesenswert?

Walter Tarpan schrieb:
> void lcd_string_P(const char *data)
> {
>     do {
>         uint8_t tmp = pgm_read_byte(data);
>         lcd_data(tmp);
>     } while (i!=0);
> }

Natürlich:
1
void lcd_string_P(const char *data)
2
{
3
    do {
4
        uint8_t tmp = pgm_read_byte(data);
5
        lcd_data(tmp);
6
    } while (tmp!=0);
7
}

"i" nervt.

von Leo C. (rapid)


Lesenswert?

Walter Tarpan schrieb:
> Mit einer do-while - Schleife kannst Du das auch noch etwas "schöner"
> machen:

Schlecht, wenn das erste Zeichen bereits '\0' sein kann.

Die übliche Formulierung geht so:
1
void lcd_string_P(const char *data)
2
{
3
  char c;
4
5
  while((c = pgm_read_byte(data++)) !=0)
6
    lcd_data(c);
7
}

hal schrieb:
> Wie kann ich sowas objektiv ermitteln?

Den Compiler-Output anschauen. Gut möglich, daß der Compiler Deine erste 
Variante schon in diese Richtung optimiert.

von Walter Tarpan (Gast)


Lesenswert?

Leo C. schrieb:
> void lcd_string_P(const char *data)
> {
>   char c;
>
>   while((c = pgm_read_byte(data++)) !=0)
>     lcd_data(c);
> }

Du hast Recht. Mal wieder die "keinen Quellcode vor dem Kaffee"-Regel 
verletzt.

Zumal meine Variante noch am Ende das Nullzeichen ausgäbe.

von (prx) A. K. (prx)


Lesenswert?

hal schrieb:
> habe ich das Gefühl, dass die Funktion 'pgm_read_byte' nicht unbedingt
> 2x innerhalb der Schleife aufgerufen werden muss.

Ich würde mir an ausgerechnet dieser Stelle keine Gedanken um 
Optimierung machen. Ein ggf. redundanter LPM Befehl braucht 
Nanosekunden, ein Zeichen an den LCD-Controller Mikrosekunden und 
Display wie Auge brauchen Millisekunden.

: Bearbeitet durch User
von hal (Gast)


Lesenswert?

Danke mal an alle.
Der Code war auch nur als Beispiel gedacht. Ob es Sinn macht oder nicht 
ist an dieser Stelle mir mal egal.

Hab jetzt genügend Info zum weitersuchen und lesen.

Beim Interpretieren der lss-Datei hab ich allerdings teilweise Problem. 
z.Bps. verstehe ich nicht, warum 'voids' doppelt vorkommen?

von Karl H. (kbuchegg)


Lesenswert?

hal schrieb:

> Beim Interpretieren der lss-Datei hab ich allerdings teilweise Problem.
> z.Bps. verstehe ich nicht, warum 'voids' doppelt vorkommen?


Weil es, nachdem sich ein Optimizer den C Code vorgenommen hat, im 
Normalfall keine eindeutige Entsprechung mehr vom Assembler Code zum C 
Code gibt. Nimm die eingestreuten C Schnipsel mehr als Hinweis, wo 
ungefähr die Originalstelle im C Code zu finden ist, aus der der 
fragliche Assembler Abschnitt entstanden ist. Letzten Endes interessiert 
nämlich sowieso nur der.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.