Forum: Compiler & IDEs Was ist schneller? AVR-GCC


von Guido S. (flintstone)


Lesenswert?

Hallo!

Für eine Berechnung habe ich drei Lösungswege. Welcher der Lösungswege 
ist der schnellste? Wie kann ich das ermitteln?

uint8_t panel;  // Panel-Nr. (0 bis 3)
uint8_t x;      // Spalte, in die geschrieben werden soll
uint8_t Col;    // Anzahl der Spalten je Panel

    panel = x / Col;   // Berechnung Panel-Nr.; für alle Lösungswege

1.  x -= Col * panel;

2.  x = x % Col;

3.  for(uint8_t i=0; i<panel; i++)
    {
      x -= Col;
    }

Für alle, die sowieso gleich fragen: Es geht um die Ansteuerung eines 
LED-Displays mit 96 x 16 Punkten.

: Verschoben durch User
von Anja (Gast)


Lesenswert?

Guido Scheidat schrieb:
> Wie kann ich das ermitteln?

einfach alle 3 Varianten im Simulator mit der Stoppuhr testen.

Gruß Anja

von Tobi (Gast)


Lesenswert?

Mess die Zeit oder guck dir den Code an, der vom Compiler erzeugt wird. 
Modulo ist aber generell ziehmlich langsam, außer wenn zur Compilezeit 
klar ist, dass nur modulo einer Zweierpotenz gerechnet wird.

Ich hatte für ein generiertes Muster, welches ich auf einem Display 
anzeigen wollte, Modulo-Operationen genutzt und der Bildaufbau war 
extrem langsam geworden.

Warum nicht einfach so:
1
if(++x >= Col) x = 0;

von spess53 (Gast)


Lesenswert?

Hi

Außer Messen kannst du auch einfach mal überlegen, welche Operationen 
der Controller von Haus aus kann. Und das sind Addition, Subtraktion und 
bei den ATMegas noch Multiplikation. Das kann er am schnellsten. Also 
ist schon

> panel = x / Col;

nicht optimal. Aus Sicht eines notorischen Assemblerprogrammierers würde 
ich dir folgendes vorschlagen (Pseudocode):

panel = 0
while x >= Col
{
  x -= Col
  inc panel
}

Kommt ohne Division aus.

MfG Spess

von Rolf M. (rmagnus)


Lesenswert?

Tobi schrieb:
> Mess die Zeit oder guck dir den Code an, der vom Compiler erzeugt wird.
> Modulo ist aber generell ziehmlich langsam, außer wenn zur Compilezeit
> klar ist, dass nur modulo einer Zweierpotenz gerechnet wird.

Allerdings wird weiter oben eine Division der selben Werte durchgeführt, 
die den Rest eigentlich eh liefert. Aber ich meine, daß der gcc das 
nicht entsprechend optimiert. Vielleicht wäre da die Funktion div() 
sinnvoll. Die liefert gleich beides zurück.
Andererseits würde ich ganz auf die Division verzichten und eher sowas 
machen:
1
panel = 0;
2
while (x >= Col)
3
{
4
    panel++;
5
    x -= Col;
6
}

Edit: Mist, wieder mal zu langsam...

von Oliver (Gast)


Lesenswert?

spess53 schrieb:
> Außer Messen kannst du auch einfach mal überlegen, welche Operationen
> der Controller von Haus aus kann. Und das sind Addition, Subtraktion und
> bei den ATMegas noch Multiplikation.

Eben. Was alles für
>x -= Col * panel;
spricht.

Oliver

von spess53 (Gast)


Lesenswert?

Hi

>Eben. Was alles für
>>x -= Col * panel;
>spricht.

Ja. Aber die 'Schnelligkeit' hat er sich schon mit 'panel = x / Col' 
versaut. Das muss in 'Software' gemacht werden. Deshalb mein Vorschlag, 
der Panel und x ohne diese Division berechnet.

MfG Spess

von Peter D. (peda)


Lesenswert?

Guido Scheidat schrieb:
> uint8_t Col;    // Anzahl der Spalten je Panel

Muß das ne Variable sein, d.h. ändert die sich wirklich zur Laufzeit?
Oder ist das eine Konstante bzw. sogar noch ne 2-er Potenz.


Peter

von Volkmar D. (volkmar)


Lesenswert?

Guido Scheidat schrieb:
> uint8_t Col;    // Anzahl der Spalten je Panel

Ist dies nicht eine Konstante? Dann würde ich es nicht als Variable 
definieren. Im Falle einer Konstanten kann der Compiler dies schon beim 
Compilieren berücksichtigen und muß es nicht zur Laufzeit machen.

Wie oft und wie wird diese Routine durchlaufen? Wie groß ist der Effekt 
auf das System?

Vielleicht kann man den Algorithmus anpassen und auf die Multiplikation 
verzichten indem dies iterativ erfolgt? Gilt zum Beispiel für den Fall 
das es aussenrum eine Schleife fürs panel von 0 nach 3 gibt.

Edit:
Peter Dannegger schrieb:
> bzw. sogar noch ne 2-er Potenz.

Nach seiner Angabe geht es um ein Display mit 96 Spalten und 4 Modulen, 
also müßte Col=24 sein.

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.