Gast
#363786
Ich muss ein paar Interrupt Routinen von C nach Assembler konvertieren,
da die Ausführungszeit zu lang ist (soll bei mir kleiner 300 Takte
sein).
Dabei ist mir aufgefallen, dass der C-Code (gcc, -Os) schon recht gut
optimiert ist.
Welche Tricks gibt es, um den ASM Code trotzdem noch weiter zu
optimieren?
Was mir eingefallen ist:
a) 24-bit Datentypen anstelle von 32-bit Datentypen benutzen
Ist oft möglich und spart bei jeder Operation ca 1/4.
b) Register über längere Zeit gültig halten, bzw. besser ausnutzen
Bringt immer wieder mal ein paar Takte. GCC nutzt nur die untere
Registerbank für länger genutzte Variablen.
c) switch() Statements
Hier ist der C-Code nicht optimal, wenn es einige case Anweisungen
gibt. Daher die switch() variable aufsteigend sortieren, mit 0
beginnen. Dann ist folgender Code meist optimaler....
// switch to lag defined by r20
ldi r30,lo8(pm(SWITCH_TAB))
ldi r31,hi8(pm(SWITCH_TAB))
add r30,r20
adc r31,R1 // R1 is zero
// new address is now in Z-register (r30/r31)
ijmp // jumps to Z
SWITCH_TAB:
rjmp LAG_0
rjmp LAG_1
d) Loop-unrolling (kann natürlich auch direkt in C gemacht werden)
Ansonsten habe ich nicht viel gefunden, ausser hier und da mal ein
Befehl. Insbesondere bei if, then, else ist gcc recht gut...
Über weitere Ideen/Vorschläge würde ich mich freuen....