mikrocontroller.net

Forum: Compiler & IDEs Multiplikationen = Performancefresser?


Autor: Detlef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

habe leider einige solcher Multiplikationen auszuführen:

for (a=0;a<max;a++){
tmp.data[a*3]=0;
tmp.data[a*3+1]=0;
tmp.data[a*3+2]=0;
}

Ich frage mich ob der Prozessor durch solche Sachen gebremst wird.
Mit 2 Multiplizieren / dividieren lässt sich ja durch Bit links/rechts 
verschiebung verschnellern. Aber bei 3 ?

Autor: Stock Hecht (winkelmesser)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Machst du noch was anderes mit a?

ansonsten : for(a=0;a<max;a=a3){...}
oder die Felder per memset() setzen...

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Code benötigt bei mir 14Bytes.
habe ich in ein vorhandenes projekt eingefügt....

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was hast Du denn für einen Prozessor? Viele Mikrocontroller haben einen 
Hardware-Multiplier. Solange Du ganzzahlig multiplizierst, sollte das 
nicht großartig lange dauern. Bei CPUs ohne Hardware-Multiplier sieht 
das anders aus. Aber eine Multiplikation mit 3 ist auch ohne 
HW-Multiplier kein Problem (a*3 = a+a+a)...

Autor: Detlef (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok, ich glaube einen HW Multi zu haben

amax ist übrigens auch nur 8

also max 3*8

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein besserer Compiler kriegt selber spitz, dass er dafür keine 
Multiplikation benötigt (strength reduction).

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Ich frage mich ob der Prozessor durch solche Sachen gebremst wird."

Nein. Der läuft immer gleich schnell.
Und wenn deine Anwendung in allen Bereichen wegen der paar 
Integer-Multiplikationen zu langsam läuft, brauchst du entweder einen 
schnelleren Quarz, oder einen schnelleren Prozessor. Kurze 
Interruptroutinen lassen sich auch von Hand optimieren. Ausserdem wird 
der Compiler mit eingeschalteter Optimierung in deinem Beispiel das a*3 
nur einmal berechnen. So schlau ist der dann doch.

Oliver

Autor: Ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
10:       tmpdata[a*3]=0;
+00000035:   8210        STD     Z+0,R1           Store indirect with 
displacement
11:       tmpdata[a*3+1]=0;
+00000036:   8211        STD     Z+1,R1           Store indirect with 
displacement
12:       tmpdata[a*3+2]=0;
+00000037:   8212        STD     Z+2,R1           Store indirect with 
displacement
9:        for (a=0;a<10;a++){
+00000038:   5081        SUBI    R24,0x01         Subtract immediate
+00000039:   9633        ADIW    R30,0x03         Add immediate to word
+0000003A:   FF87        SBRS    R24,7            Skip if bit in 
register set
+0000003B:   CFF9        RJMP    PC-0x0006        Relative jump
17:       }

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
fehlt da jetzt nicht der Teil mit der Berechnung des Wertes für Z? Das 
wäre ja das interessante, oder nicht?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast wrote:
> fehlt da jetzt nicht der Teil mit der Berechnung des Wertes für Z? Das
> wäre ja das interessante, oder nicht?

Der springende Punkt ist, dass in der Berechnunug von Z keine
Multiplikation mit 3 mehr vorkommt.

Der Compiler ist ein ganz ein schlauer.
Er hat gemerkt, dass er in der Schleife

for (a=0;a<10;a++){

das Z Register einfach nur um 3 erhöhen muss

9633        ADIW    R30,0x03

um die Multiplikation einzusparen.
Aus der Schleife

for (a=0;a<10;a++){
  tmpdata[a*3]=0;
  tmpdata[a*3+1]=0;
  tmpdata[a*3+2]=0;
}

macht der Compiler
                           Z_Pointer = Basispointer tempdata[0]
                           a = 9

  STD     Z+0,R1           *(Z_Pointer) = 0
  STD     Z+1,R1           *(Z_Pointer+1) = 0
  STD     Z+2,R1           *(Z_Pointer+2) = 0
  SUBI    R24,0x01         a = a - 1
  ADIW    R30,0x03         Z_Pointer = Z_Pointer + 3
  SBRS    R24,7            Unterlauf bei a = a - 1?
  RJMP    PC-0x0006        Nein -> nächster Durchgang

(Die Initialisierung des Z Registers mit der Basisadresse von
tmpdata, sowie die Vorbelegung von R24 mit 9 ist nicht gezeigt.
Du kannst dir aber denken wie die aussieht).
Sei ehrlich: besser hättest du das auch nicht hingekriegt.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ahhh... er hat quasi sowas wie:

Index = 0;
for(a=9;a>=0; a--)
{
  tmpdata[Index] = 0;
  tmpdata[Index+1] = 0;
  tmpdata[Index+2] = 0;

  Index += 3;
}

draus gemacht?
Das is ja geschickt. Macht er das immer oder nur bei eingeschalteten 
Optimierungen?

Gast.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gast wrote:
> ahhh... er hat quasi sowas wie:
>
> Index = 0;
> for(a=9;a>=0; a--)
> {
>   tmpdata[Index] = 0;
>   tmpdata[Index+1] = 0;
>   tmpdata[Index+2] = 0;
>
>   Index += 3;
> }
>
> draus gemacht?

So ähnlich

  unsigned char* data = tmpdata;
  for(a=9;a>=0; a--)
  {
    *data = 0;
    *(data + 1) = 0;
    *(data + 2) = 0;
    data += 3;
  }

Für die Arrayindizierung bräuchte er ja wieder eine
Multiplikation. Aber du hast das Prinzip schon richtig
erkannt :-)

> Das is ja geschickt.

Gelle. So ein Compiler hat heutzutage schon eine Menge
Optimierungen drauf. Manchmal haut er gcc-Optimizer auch
ein bischen daneben. Das liegt aber daran, dass der gcc
nicht nur für µC gebaut ist, sondern eine breite Palette
von Prozessoren, bis hin zu Grossrechnern abdecken muss.
Und dann gibt es noch den C Standard, der manchmal eine
Optimierung, die ein Assemblerprogrammierer machen würde,
verhindert.

> Macht er das immer oder nur bei eingeschalteten
> Optimierungen?

Die muessen schon eingeschaltet sein.
Der Grund dafür ist: Wenn du so eine Optimierung im Debugger
duchsteppst, dann erkennst du den Programmfluss nicht mehr
wieder: Zeilen werden in seltsamen Reihenfolgen ausgeführt,
Variablen ändern ihren Wert nicht so, wie man es aus dem
C-Quellcode erwarten würde, etc.
Beim Debuggen wäre sowas verwirrend, also sollte man zum
Debuggen eine Möglichkeit haben, Optimierungen gänzlich
abzuschalten.

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.