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....
Versuch vielleicht mal testweise mit -O3 zu kompilieren, und vergleich den ASM code. Wenn der gcc da nicht unbedingt ein kleines File draus machen will, findet der vielleicht selbst noch was. /Ernst
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.