mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie kann ich Bitschieberei beschleunigen


Autor: AVR Anfänger (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ich brauche innerhalb meiner Timerinterruptroutine eine Bitschieberei 
wie im Bild gezeigt.
ich habe das so in C programmiert:
unsigned short int Bla1;
unsigned short int Bla2;
unsigned short int Bla3;
unsigned short int Bla4;
unsigned short int Bla5;
unsigned char Blub;


int main(void)
{
//Hier passiert noch viel anderes,
//was jetzt unwichtig ist!





}

//********************************************

ISR(TIMER1_OVF_vect)

{
//Hier passiert noch viel anderes,
//was jetzt unwichtig ist!

      Blub = (Bla1 & 0x8000)>>15 
          |(Bla2 & 0x8000)>>14
          |(Bla3 & 0x8000)>>13
          |(Bla4 & 0x8000)>>12      
          |(Bla5 & 0x8000)>>11;

}
Das funktioniert auch, könnte aber schneller sein.
In Pseudo-Assembler würde ich das etwas so schreiben:
    CLR   R9
    MOV   R10,Highbyte[Bla5]
    ROL   R10
    ROL   R9
    MOV   R10,Highbyte[Bla4]
    ROL   R10
    ROL   R9
    MOV   R10,Highbyte[Bla3]
    ROL   R10
    ROL   R9
    MOV   R10,Highbyte[Bla2]
    ROL   R10
    ROL   R9
    MOV   R10,Highbyte[Bla1]
    ROL   R10
    ROL   R9
    MOV   [Blub],R9
Ich arbeite mit AVR Studio4, GCC und meine CPU ist ein ATtiny25
Was kann ich in C tun um meine Bitschieberei zu beschleunigen?

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

Bewertung
0 lesenswert
nicht lesenswert
AVR Anfänger schrieb:

> Was kann ich in C tun um meine Bitschieberei zu beschleunigen?

Gar nicht schieben?
     Blub = ( ( Bla1 & 0x8000 ) ? 0x10 : 0x00 ) |
            ( ( Bla2 & 0x8000 ) ? 0x08 : 0x00 ) |
            ( ( Bla3 & 0x8000 ) ? 0x04 : 0x00 ) |
            ( ( Bla4 & 0x8000 ) ? 0x02 : 0x00 ) |      
            ( ( Bla5 & 0x8000 ) ? 0x01 : 0x00 ) );

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR Anfänger schrieb:
>       Blub = (Bla1 & 0x8000)>>15
>           |(Bla2 & 0x8000)>>14
>           |(Bla3 & 0x8000)>>13
>           |(Bla4 & 0x8000)>>12
>           |(Bla5 & 0x8000)>>11;
> [...]
> Ich arbeite mit AVR Studio4, GCC und meine CPU ist ein ATtiny25
> Was kann ich in C tun um meine Bitschieberei zu beschleunigen?
Mein erster Gedanke:
Du musst doch nicht zwingend schieben, du kannst doch einfach Konstanten 
verodern:

Blub = 0;
if (Bla1 & 0x8000) Blub |= 1;
if (Bla2 & 0x8000) Blub |= 2;
if (Bla3 & 0x8000) Blub |= 4;
   :
   :

Gruß,
Bernd

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

In Assembler braucht man überhaupt nichts schieben. Der Bittransfer geht 
einfacher über das T-Flag im Statusregister mit 'bld' und 'bst'. Braucht 
pro Bit 2 Befehle.

MfG Spess

Autor: AVR Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die schnellen Antworten.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Fies ist, dass GCC praktisch alle Versuche, Schiebeoperationen zu 
vermeiden, ziemlich konsequent als solche identifiziert und auf die 
Schiebeoperation zurückführt.

Irgendwann kam wohl mal ein kluger Geist drauf, dass alle Prozessoren 
(die er kannte?) billige Schiebeoperationen besitzen. Billiger 
jedenfalls als Sprünge. Also optimiert man alles was irgendwie geht 
entsprechend um. Und weil das so selbstverständlich ist muss man, anders 
als sonst, dafür auch keinen eigenen Schalter vorsehen.

Und irgendwie fehlt entweder dem AVR backend die richtige Peilung über 
die Kosten von Operationen, oder diese Optimierungsstufe fragt danach 
erst garnicht. Und so werden eben bei AVRs billige set-conditional 
Operationen (über skip conditional) durch sauteure Schiebeschleifen 
ersetzt.

Auch KHBs und Bernds Versionen werden von avr-gcc 4.3.4 entsprechend 
grauenvoll umgearbeitet

Es gab hier mal einen Thread dazu.

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

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:

> Auch KHBs und Bernds Versionen werden von avr-gcc 4.3.4 entsprechend
> grauenvoll umgearbeitet

Ehrlich?
Das ist in der Tat fies!

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Auch KHBs und Bernds Versionen werden von avr-gcc 4.3.4 entsprechend
> grauenvoll umgearbeitet
Hast Du's wirklich ausprobiert oder geraten?

Ich hab's gerade mal durch den avr-gcc-4.3.3 laufen lassen, da sieht 
zumindest meine Version ganz ordentlich aus:

    Blub = 0;

    if (Bla1 & 0x8000) Blub |= 1;
    if (Bla2 & 0x8000) Blub |= 2;
 100:   57 fd           sbrc    r21, 7
 102:   32 60           ori r19, 0x02   ; 2
    if (Bla3 & 0x8000) Blub |= 4;
 104:   77 fd           sbrc    r23, 7
 106:   34 60           ori r19, 0x04   ; 4
    if (Bla4 & 0x8000) Blub |= 8;
 108:   f7 fd           sbrc    r31, 7
 10a:   38 60           ori r19, 0x08   ; 8
    if (Bla5 & 0x8000) Blub |= 16;
 10c:   b7 fd           sbrc    r27, 7
 10e:   30 61           ori r19, 0x10   ; 16

    target = Blub;
 110:   39 83           std Y+1, r19    ; 0x01


Gruß,
Bernd

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo ist bla1 abgeblieben?

Autor: A. K. (prx)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Bernd O. schrieb:

> Hast Du's wirklich ausprobiert oder geraten?

Anbei. Nicht wörtlich aber sinngemäss. Es wird nicht alles umgearbeitet,
aber stets mindestens eine der Operationen.

Autor: Bernd O. (bitshifter)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Wo ist bla1 abgeblieben?

Vor meinem Code kam der Schiebe-Code von "AVR-Anfänger", der wohl R19 
schon "vorbehandelt" hat, weshalb für das erste Bit nichts mehr zu tun 
war.

Ich habe jetzt den Schiebe-Code entfernt und es sieht nun folgendermaßen 
aus:

    Blub = 0;

    if (Bla1 & 0x8000) Blub |= 1;
  b2:   8b 2f           mov r24, r27
  b4:   88 1f           adc r24, r24
  b6:   88 27           eor r24, r24
  b8:   88 1f           adc r24, r24
    if (Bla2 & 0x8000) Blub |= 2;
  ba:   57 fd           sbrc    r21, 7
  bc:   82 60           ori r24, 0x02   ; 2
    if (Bla3 & 0x8000) Blub |= 4;
  be:   77 fd           sbrc    r23, 7
  c0:   84 60           ori r24, 0x04   ; 4
    if (Bla4 & 0x8000) Blub |= 8;
  c2:   37 fd           sbrc    r19, 7
  c4:   88 60           ori r24, 0x08   ; 8
    if (Bla5 & 0x8000) Blub |= 16;
  c6:   f7 fd           sbrc    r31, 7
  c8:   80 61           ori r24, 0x10   ; 16

    target = Blub;
  ca:   89 83           std Y+1, r24    ; 0x01

Gruß,
Bernd

Autor: AVR Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die vielen Antworten, ihr gebt euch echt Mühe.
Nur leider habe ich unheimlich viele Variablen in meinem Programm.
Deshalb glaube ich nicht, das der Compiler die alle in Registern anlegen 
wird. Man könnte das dem Compiler vieleicht vorschlagen:
register unsigned short int Bla1;
register unsigned short int Bla2;
register unsigned short int Bla3;
register unsigned short int Bla4;
register unsigned short int Bla5;

Aber die "register" anweisung ist für den Compiler nicht wirklich 
bindend.
(Glaube ich mal irgendwo gelesen zu haben)

Autor: AVR Anfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist "adc r24, r24" das selbe wie "rol r24" ?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Un bist du sicher das diese "optimierung" an der richtigen Stelle ist?

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
AVR Anfänger schrieb:

> Aber die "register" anweisung ist für den Compiler nicht wirklich
> bindend. (Glaube ich mal irgendwo gelesen zu haben)

Korrekt.

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.