Das ist dann das Henne-Ei Paradoxon, wenn Du nicht Assembler lesen kannst, siehst Du nicht, wie der Compiler bestimmte Anweisungen in C umsetzt, das Du deswegen benutzt um Assembler zu vermeiden![]()
Das ist dann das Henne-Ei Paradoxon, wenn Du nicht Assembler lesen kannst, siehst Du nicht, wie der Compiler bestimmte Anweisungen in C umsetzt, das Du deswegen benutzt um Assembler zu vermeiden![]()
Da geb ich Dir Recht
Ich finde ASM einfach so unbequem, aber wo keine Rechenleistung ist, muss man eben durch Optimierung nachhelfen, mir bleibt da wohl nichts übrig...
Das Ersetzen von (mFlag<<M) durch mFlag bringt so gut wie nichts.
mFlag wird dabei vorher schon 0x08 oder 0x00 gesetzt.
Geändert von MisterMou (02.05.2012 um 23:55 Uhr)
Du hast halt das Problem dass aus 2 schnöden Takten, oft genug durchlaufen, schnell mal 1000 werden.
Ich fand den erzeugten ASM-Block zum Steuern der Bits unnötig kompliziert, hab' mich allerdings nicht um andere Lösungen umgesehen.
Mir wär's allerdings zu dumm mit dem C-Code rumtüfteln zu müssen, nur damit der Compiler das von mir Gewünschte zusammenbaut. Hatte ich am Anfang des Projekts auch versucht, nur um zu erkennen, was da alles an kreativ Unbrauchbarem rauskommt.
Dann sag' ich's doch gleich in Assembler, vor allem da der Umfang der Sache recht überschaubar ist.
Geändert von MagicWSmoke (03.05.2012 um 00:00 Uhr)
Hab' mir nochmal angesehen, warum Dein Code so langsam ist. Hier:
hatte ich bereits richtig geraten. Auch wenn ich die (mFlag<<M) Geschichte nicht gut finde, weil er da in einer Schleife schiebt, was völlig unnötig ist, da vermeidbar, so wird dieser Teil nicht oft durchlaufen....dass aus 2 schnöden Takten, oft genug durchlaufen, schnell mal 1000 werden.
Das Problem macht dies hier:
Denn das wird 40 mal pro ISR eingebaut und ist das Resultat aus:Code:mov r25,r21 ldi r24,k00 subi r24,k00 sbci r25,kFF
So etwas kannst Du vermeiden, indem Du zu Beginn der ISR die globale Variable in eine lokale kopierst und am Ende wieder zurück. Damit erlaubst Du dem Compiler zu optimieren, d.h. diese lokale Variable in einem Prozessorregister zu halten.Code:: "r" (&font[charRow][0]), "r" (tempChar) \
Spart pro ISR-Lauf ca. 160 Takte, macht dann bei 12 x 20 x 75 = ~2900000 TakteCode:#define char_put() \ ... : "r" (&font[l_charRow][0]), "r" (tempChar) \ ... } ISR(TIMER0_OVF_vect) { unsigned char l_charRow = charRow; ... if(l_charRow==CHAR_HEIGTH) ... l_charRow=0; ... l_charRow++; charRow = l_charRow; }
Geändert von MagicWSmoke (03.05.2012 um 10:19 Uhr)
Um solche Infos geht es mir, danke. Das hatte ich bis jetzt nirgendwo gelesen (vllt. auch überlesen), dabei ist es doch so wichtig für ein schnelles Programm...So etwas kannst Du vermeiden, indem Du zu Beginn der ISR die globale Variable in eine lokale kopierst und am Ende wieder zurück. Damit erlaubst Du dem Compiler zu optimieren, d.h. diese lokale Variable in einem Prozessorregister zu halten.
Bin damit auf eine Auslastung von 70% bei 75Hz gefallen, da fehlt nicht mehr viel zur ASM Version
Bei 50Hz sind es 47% Auslastung.
Aktueller Stand:
Geändert von MisterMou (03.05.2012 um 11:35 Uhr)
Dachte ich mir
http://www.mikrocontroller.net/artic...tile-VariablenDas hatte ich bis jetzt nirgendwo gelesen (vllt. auch überlesen), dabei ist es doch so wichtig für ein schnelles Programm...
70% halt' ich für ein Gerücht, die Assembler-ISR hatte im Schnitt um die 650 Takte, daraus ergibt sich 73% Last, die C-Version mit 680 Takten hat dann um die 76 %.Bin damit auf eine Auslastung von 70% bei 75Hz gefallen, da fehlt nicht mehr viel zur ASM Version![]()
Dann muss mein Oszi lügen. Nagut die "Messung" ist nicht optimal
Bild hier
Bei Dir klang das neulich noch nach weniger als 66%
edit: Jaja, ich hab mich verrechnet, sind 75%![]()
Geändert von MisterMou (03.05.2012 um 12:52 Uhr)
Lesezeichen