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
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
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.
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.
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:
1
registerunsignedshortintBla1;
2
registerunsignedshortintBla2;
3
registerunsignedshortintBla3;
4
registerunsignedshortintBla4;
5
registerunsignedshortintBla5;
Aber die "register" anweisung ist für den Compiler nicht wirklich
bindend.
(Glaube ich mal irgendwo gelesen zu haben)
AVR Anfänger schrieb:
> Aber die "register" anweisung ist für den Compiler nicht wirklich> bindend. (Glaube ich mal irgendwo gelesen zu haben)
Korrekt.