Forum: Compiler & IDEs AVR Optimierung verbessern


von Michael H. (overthere)


Lesenswert?

Hallo zusammen,

schaut euch mal bitte folgenden Code an:
1
if(my16bitpointer>=(constant)){
2
 13e:  80 e0         ldi  r24, 0x00  ; 0
3
 140:  ef 37         cpi  r30, 0x7F  ; 127
4
 142:  f8 07         cpc  r31, r24
5
 144:  10 f0         brcs  .+4        ; 0x14a <__vector_13+0x3a>

Hier soll der AVR den 16 Bit pointer vergleichen; dabei belegt er aber 
R24 mit einer Null obwohl R0 schon diesen Wert enthält. Es wäre viel 
geschickter, stat R24 R0 zum verlgeichen zu nehmen. Man spart ohne viel 
aufwand 1 Register und ein Befehl.

Kann man das dem GCC irgendwie beibringen? (Bin leider absolut 
inkompentent im Compilerbau!)

Grüße

Michael

von (prx) A. K. (prx)


Lesenswert?

Da es um einem Pointer geht nehme ich an, dass die Konstante eine 
Adresse ist. Deren Wert kennt erst der Linker. Der Compiler kennt ihn 
nicht, weiss also nicht, dass das obere Byte davon 0 ist.

von Michael H. (overthere)


Lesenswert?

Ja, du hast recht, es ist ne Adresse. Also schade. Geht das also 
defintiv nicht?

von (prx) A. K. (prx)


Lesenswert?

Nur indem du den Wert der Adresse dort angibst. Also
 if(my16bitpointer>=(sonstwas *)0x7F){
Wär natürlich besser, wenn das auch in der nächsten Version immer noch 
0x7F ist, sonst...

von Michael H. (overthere)


Lesenswert?

Stop, es sollte doch gehen! Der AVR hat per Definiton (Tiny24) nur 8 
Bitram Adressen. Also müsste es der Compiler doch auch wissen. Aber das 
ist wohl aufwendiger als das Ergebnis.
Diese Manuelle Konstruktion halte ich für ein Spiel mit dem Feuer. Wehe, 
das ist dann nachher nicht mehr so...
Gibt es eine Möglichkeit, die 16 Bit Pointer auf 8 Bit Pointer zu 
reduzieren? (da der AVR nur 128 Byte Ram hat)

von (prx) A. K. (prx)


Lesenswert?

Michael H. schrieb:

> Stop, es sollte doch gehen! Der AVR hat per Definiton (Tiny24) nur 8
> Bitram Adressen. Also müsste es der Compiler doch auch wissen. Aber das
> ist wohl aufwendiger als das Ergebnis.

Ok, du hast Recht. Nur müsste sich jetzt noch jemand finden, der für die 
paar Tinys mit Datenadressraum bis 256 Bytes den Compiler auf den Kopf 
stellt.

> Gibt es eine Möglichkeit, die 16 Bit Pointer auf 8 Bit Pointer zu
> reduzieren? (da der AVR nur 128 Byte Ram hat)

Aber sicher. Der GCC Quellcode ist bekanntlich offen. Es hindert dich 
niemand daran, eine avr-gcc Version zu stricken, die für Pointer nur 8 
Bits verwendet. Allerdings wird Datenzugriff auf das ROM dann noch etwas 
umständlicher als er ohnehin schon ist, denn auch diese Pointer sind 
dann 8 Bit "breit".

von Michael H. (overthere)


Lesenswert?

Okay, ich glaube das war ein Overkill. Ich kapituliere.

Noch eine Frage, gibt es eine Möglichkeit den Prolog zu überarbeiten? 
Z.B. würde ich gerne __do_copy_data oder das rcall durch ein rjmp 
ersetzen. Das würde ich mir in Assembler zutrauen.

von (prx) A. K. (prx)


Lesenswert?

Du weisst aber schon, dass man statt krampfig ein paar Bytes einzusparen 
auch einen Tiny44 verwenden kann, oder?

von Flo (Gast)


Lesenswert?

Wenn du Optimierung willst, schreib dein Programm in Assembler :D

von Hc Z. (mizch)


Lesenswert?

Der Compiler weiß nicht, auf was ein Pointer zeigt.  Es kann genauso gut 
wie RAM eine Adresse im Flash sein, und da reichen 8 Bit nicht.

Einen Pointer, der nur auf Ram zeigen kann, gibt es in AVR-GCC nicht.

von (prx) A. K. (prx)


Lesenswert?

Hc Zimmerer schrieb:

> Einen Pointer, der nur auf Ram zeigen kann, gibt es in AVR-GCC nicht.

Andersrum. Von Funktionszeigern mal abgesehen gibt es, was den Compiler 
angeht, nur solche Pointer. Deshalb kann man ja das Flash auch nur mit 
Murks wie pgm_read_byte erreichen.

von Michael H. (overthere)


Lesenswert?

Was mich stört ist der überzogene Prolog.
Wie kann ich den optimieren?

@Flo: Das problem ist, wenn ich alles in ASM schreibe, verliere ich den 
Überblick.
@prx: Ich habe halt meinen Spass am optimieren. Ich empflinde das nicht 
als Krampf.

von Hc Z. (mizch)


Lesenswert?

Nein.  pgm_read_byte brauchst Du nur beim Dereferenzieren eines 
Pointers.  Für den Pointer selbst ist es egal, ob er ins  Rom zeigt oder 
ins Ram.  C kennt keine solche Unterscheidung.

von (prx) A. K. (prx)


Lesenswert?

Ob ROM oder RAM ist ihm egal, ob Codespace oder Dataspace nicht. Bei 
AVRs ist dieser Unterschied allerdings deckungsgleich.

Ein Compiler, der bei einer C-konformen Dereferenzierung jene 
Prozessor-Befehle verwendet, die RAM/Dataspace ansprechen, versteht 
einen solchen Pointer offenkundig als Pointer auf RAM/Dataspace. Auch 
wenn C diese Unterscheidung nicht kennt, der AVR-Compiler als Brücke 
zwischen C und Maschine kennt sie.

Dass man einem solchen Pointer auch Adressen im ROM/Codespace oder im 
EEPROM zuweisen kann, das ist genau genommen ein absichtlich übersehener 
Fehler beim Linken.

von Rolf Magnus (Gast)


Lesenswert?

A. K. schrieb:
> Auch wenn C diese Unterscheidung nicht kennt, der AVR-Compiler als
> Brücke zwischen C und Maschine kennt sie.

Nein, der Compiler kennt sie eben nicht, zumindest im Falle von gcc. Das 
ist ja das Problem. Als Krücken zur Unterscheidung dienen 
Bibliotheksfunktionen und Tricks im Linkerskript.

> Dass man einem solchen Pointer auch Adressen im ROM/Codespace oder im
> EEPROM zuweisen kann, das ist genau genommen ein absichtlich
> übersehener Fehler beim Linken.

Dem Linker sind Zeigerwerte eigentlich ziemlich egal.

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.