Forum: Compiler & IDEs Idee für Optimierung? (Scope-Clock auf Speed)


von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Hi,

ich sucht nach Ideen für Geschwindigkeits-Optimierung des C-Codes für 
meine Scope-Clock. Eckdaten:

-- ATmega168 @ 24 MHz
-- IRQ-Rate = 48000/s, d.h. 500 Ticks/IRQ

IdR wird pro IRQ ein Pixel an einen 8-Bit DAC ausgegeben. Weil die 
Anzeige eine Röhre ist liegen harte Echtzeit-Bedingungen vor. Wie bei 
einem Händi, wo die Möglichkeit damit zu Telefonieren nur Nebensache 
ist, so sind auch bei meiner Scope-Clock Spielchen wie Snake oder 
Asteroids wichtiger als die UHr-Funktion und die wahren 
Ressourcen-Fresser an Flash, RAM und Zeit.

Nach Möglichkeit sind Berechnungen natürlich in die main-Loop 
ausgelagert, aber aufgrund des kleinen RAMs von 1k ist nicht alles 
vorberechenbar, weil es schlicht und einfach nicht gespeichert werden 
kann. Eine FIFO-Lösung habe ich verworfen, weil der Overhead zur 
FIFO-Verwaltung zu viel der wertvollen Rechenzeit auffraß.

Dennoch verbleibt in der Pixel-ISR sehr viel zu tun, und die "goldene" 
Regel, ISRs möglicht kurz zu halten ist schlichtweg nicht umsetzbar.

Von den 500 Ticks, die eine ISR zur Verfügung hat, entfallen alleine ca. 
100 Ticks, also 20% der Zeit, auf ISR-Prolog und -Epilog! Der ISR-Aufbau 
sieht momentan so aus (schematisch):
1
ISR
2
{
3
    int count = 0;
4
5
    do {
6
       mach_was();
7
8
       if (!IRQ_Flag)
9
          break;
10
       clear (IRQ_Flag);
11
    } while (++count < 10);
12
}

Durch die do-Schleife wird ein ISR-Frame gespart, wenn mach_was() lange 
gedauert hat und der nächste ISR-Beginn überfällig ist.

Irgendwie will ich nicht so ganz glauben, daß es da keine bessere Lösung 
für gibt als 20% der Zeit auf Pro- und Epilog zu verheizen.

Ich hatte schon überlegt, das Design auf den Kopf zu stellen, also 
mach_was() als einzige Funktion in der main-Loop zu haben und per 
Soft-IRQ die Berechnungen zu machen, die jetzt in der main stehen. Aber 
damit kommt man wohl vom Regen in die Traufe...

Kann man das geschickter angehen? mach_was() kann übrigens nicht 
geinlinet werden, da es indirekt aufgerufen wird.

Johann

von Stefan Salewski (Gast)


Lesenswert?

Ganz trivial, bringt auch fast nichts, evtl. gar nichts, wenn gcc klug 
ist:

int count = 10;

while (--count);

Ich würde es aber stets so schreiben...
Andere wissen sicher mehr.

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:

> Irgendwie will ich nicht so ganz glauben, daß es da keine bessere Lösung
> für gibt als 20% der Zeit auf Pro- und Epilog zu verheizen.

Klingt nach Assembler. Mit einem Satz von Registern der ausschliesslich 
der ISR zur Verfügung steht. Damit entfallen sämtliche PUSH/POPs und die 
Daten stehen ausserdem schon in den Registern. AVR hat ja genug für 
solche Methoden.

Das mit C zu kombinieren wird allerdings kritisch. Register 
ausschliessen geht ja - im Prinzip. Evtl. möglich, wenn man nur eigenen 
Quellcode verwendet und die verbleibenden Runtime-Funktionen draufhin 
kontrolliert welche Regs sie verwenden.

von Stefan Salewski (Gast)


Lesenswert?

>mach_was();

Der Prozeduraufruf und der zugehörige Rücksprung kostet natürlich auch 
Zeit, also Code evtl. direkt hinschreiben.

von Rolf Magnus (Gast)


Lesenswert?

> Kann man das geschickter angehen? mach_was() kann übrigens
> nicht geinlinet werden, da es indirekt aufgerufen wird.

Muß das so sein?  Das wird der Hauptgrund sein, daß Prolog und Epilog so 
lange dauern. Weil du einen nicht-inline-Funktions-Aufruf drin hast, 
sichert die ISR vorsichtshalber mal alle Register. Das kostet massig 
Zeit.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> Johann L. schrieb:
>
>> Irgendwie will ich nicht so ganz glauben, daß es da keine bessere Lösung
>> für gibt als 20% der Zeit auf Pro- und Epilog zu verheizen.
>
> Klingt nach Assembler. Mit einem Satz von Registern der ausschliesslich
> der ISR zur Verfügung steht. Damit entfallen sämtliche PUSH/POPs und die
> Daten stehen ausserdem schon in den Registern. AVR hat ja genug für
> solche Methoden.

Nicht wirklich. Zeiger-Register hat man effektiv nur 3, welche über die 
man mehr oder weniger effektiv auf Strukturen zugreifen kann nur 2 (Y 
und Z) und für Zugriff auf Flash-Tabellen nur eines (Z).

> Das mit C zu kombinieren wird allerdings kritisch. Register
> ausschliessen geht ja - im Prinzip. Evtl. möglich, wenn man nur eigenen
> Quellcode verwendet und die verbleibenden Runtime-Funktionen draufhin
> kontrolliert welche Regs sie verwenden.

Eigentlich bin ich ganz froh, daß ich geschafft hab die Software zu 95% 
in C hinzubekommen. Ähnliche Projekte implementieren komplett in 
Assembler oder nutzen andere Hardware wie FPGA, mehrere Prozessoren oder 
32-Bit Boliden.

In Assembler sind lediglich Teile der Arithmetik, die von avr-gcc nicht 
unterstützt werden wie _Sat (Saturierte Operatoren) und _Frac (1.7 und 
1.15 Q-Format). Die Q-Format Operatoren brauchen Register der Klasse 
"a", also aus R16...R23, und avr-gcc hat sinnvollerweise auch eine 
Starke Präferenz für diese Register zur Parameterübergabe. Zudem 
erlauben sie LDI, CPI, SBCI, SUBI und CPCI.

Das Programm hat run 10000 Zeilen C-Code. Das in Assembler zu hacken 
will ich mir nicht antun.

Fixe Register gibt's schon ne handvoll
-- Eines enthält die Null (ohne daß es durch MUL* zerstört wird)
-- Je eins für die zu setzenden x/y-Koordinaten. Damit kann jede
   in 2 Ticks und 2 Befehlen die Koordinaten setzen.
-- 2 Register sind als Zwischenregister bei der Fix-Arithmetik
   reserviert und müssen so nicht gesichert werden
-- Zur Kommunikaton gibt's ein Bit-Adressierbares SFR (GPIOR0)

Johann

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:

> Das Programm hat run 10000 Zeilen C-Code. Das in Assembler zu hacken
> will ich mir nicht antun.

Oha. Kann ich verstehen. Aber ich meinte nicht das gesamte Programm, 
sondern den Interrupt-Code.

Wieviele mach_was() Varianten gibt es denn? Wenn es nicht zu viele sind, 
kann es sich lohnen, an Stelle der Indirektion ein paar Abfragen zu 
setzen. Dann geht Inlining wieder.

von (prx) A. K. (prx)


Lesenswert?

Was ist denn die eigentliche Zielrichtung der Optimierung? Die von dir 
gestellte Frage ist sehr konkret, aber dass du an der Struktur der ISR 
nur begrenzt drehen kannst ohne dem GCC ein neues Registermodell 
beizubringen ist dir ja selber schon klar. Insofern vielleicht zu 
konkret. Muss es wohl eher darum gehen, die Häufigkeit von Interrupts zu 
reduzieren.

Dass du durch den Overhead von Interrupts Zeit verlierst ist kaum zu 
vermeiden. Inwieweit sich die Interrupts durch einen anderen Ansatz 
reduzieren lassen musst du selber wissen, dazu liegt mir nicht genug 
Information vor. Die Umkehrung hast du ja selber schon erwähnt.

Eine rohe Idee will ich noch einbringen, wobei ich mangels Einblick in 
die Aufgabe keine Ahnung habe ob das was bringt: Wenn eine 
Interrupt-Routine ohnehin alles sichert, dann ist der zeitliche 
Unterschied zwischen klassischen Interrupts und Contextswitches in 
zeiteffizienten RTOS-Kernels wie AvrX nicht allzu gross.

Das mag zunächst etwas paradox klingen, denn es kommt im Prinzip etwas 
Overhead hinzu und das reduziert auch nicht den Zeitverlust von 
Interrupts. es könnte aber möglicherweise die Umstellung der 
Arbeitsweise auf deutlich andere Ansätze programmiertechnisch 
erleichtern um so vielleicht die Anzahl Interrupts/Contextswitches zu 
reduzieren. Oder zumindest die verfügbare Rechenzeit auf die vorrangige 
Tätigkeit konzentrieren.

von (prx) A. K. (prx)


Lesenswert?

Mehr Brainstorming: Eine extremere Form solcher Programmiertechnik sind 
Adam Dunkels' protothreads. Reaktion auf Events ohne komplexe 
Statemachines, teure Interrupts und teure Contextswitches. Aber 
natürlich mit anderen Kehrseiten.

von Johann L. (gjlayde) Benutzerseite


Angehängte Dateien:

Lesenswert?

A. K. schrieb:
> Johann L. schrieb:
>
>> Das Programm hat run 10000 Zeilen C-Code. Das in Assembler zu hacken
>> will ich mir nicht antun.
>
> Oha. Kann ich verstehen. Aber ich meinte nicht das gesamte Programm,
> sondern den Interrupt-Code.

Der ISR-Code ist lange

Geschätzte 7000 Zeilen.

> Wieviele mach_was() Varianten gibt es denn? Wenn es nicht zu viele sind,
> kann es sich lohnen, an Stelle der Indirektion ein paar Abfragen zu
> setzen. Dann geht Inlining wieder.

Inlining ist aber nur dann sinnvoll, wenn in der kompletten Call-Chain 
kein einziger Funktionsaufruf mehr überig bleibt!

Die Call-Chain ist zwar recht flach, aber die einzelnen Funktionen 
zersplitter in viele Fallunterscheidungen und werden oft mehrfach 
verwendet.

A. K. schrieb:
> Was ist denn die eigentliche Zielrichtung der Optimierung? Die von dir
> gestellte Frage ist sehr konkret, aber dass du an der Struktur der ISR
> nur begrenzt drehen kannst ohne dem GCC ein neues Registermodell
> beizubringen ist dir ja selber schon klar. Insofern vielleicht zu
> konkret. Muss es wohl eher darum gehen, die Häufigkeit von Interrupts zu
> reduzieren.

Die Anzahl der IRQs kann ich zwar runterschrauben, das geht aber auf die 
Qualität der Grafik: Die Maximalzahl der Pixel, die gezeichnet werden 
können, ohne daß die Röhre flimmert, wird kleiner.

Der GJ-Schirm fängt an zu flimmern bei weniger als ca. 30-35 Frames pro 
Sekunde. Pro Frame bleiben also F_CPU/(FRAMES * TICKS-pro-ISR) Pixel, 
momentan also ca. 1200 Pixel / Frame. Damit ist SPielgeschehen wie bei 
Asteroids oder Snake vernünftig darstellbar.

Bei der Optimierung kämpf ich an allen Fronten: Zeit, Flash und RAM. Um 
es etwas konkreter zu machen hab ich mal den aktuellen Snapshot des 
Projekts angehängt. Ist viel Code, teilweise unkommentiert Spaghetti, 
also net erschrecken ;-) Der grobe Ablauf der Pixel-Erzeugung ist 
beschrieben in menu.c:49, wo sich auch die Hauptscheife befindet 
(menu.c:254)

Die Pixel-ISR um die es geht steht in main.c (SIG_OUTPUT_COMPARE2A) und 
darunter wird zum Pixel-Handler menu.item.onPixel (Zeile main.c:151) 
verzweigt.

Jeder Menü-Punkt hat seinen eigenen Pixel-Handler. Menü-Punkte gibt es 
jeweils am Ende von uhr.c, snake.c, asteroids.c, text.c, textmenu.c, 
testbild.c, schoner.c und dcf-oszi.c. Also 8 Stück.

Diese Routinen verwenden teilweise Unterroutinen wie Bresenham (Linie 
zeichnen in bresenham.c) oder Vektor-Font pixeln (in vektor-zeichen.c)

Alleine das Pixeln des Vector-Fonts zu inlinen würde den Code 
explodieren und vermutlich sogar langsamer machen. Momentan braucht 
keine Funktion im Projekt einen Frame-Pointer (ausser varargs-Ausgabe 
aufs Terminal in uput.c)

Die RAM-Optimierung geht über gemeinsam verwendeten Speicher, der in 
einer Union in frame.h organisiert ist. Das geht weil immer nur 1 
Menüpunkt aktiv sein kann (über Recover nach Bildschirmschoner hab ich 
mir noch keine Gedanken gemacht). Ohne diese Technik wäre schon längst 
das RAM aus (momentan statisch belegt sing ca 2/3 von 1k)

Hauptziel der Optimierung sind aber Code (momentan belegt 80% von 16k) 
und Geschwindigkeit, wobei da vor allem die WCET interessant ist, also 
die Maximalzeit (worst code execution time).

onPixel setzt ja immer nur 1 Pixel. mach_was() (bzw. onPixel) stellen 
also den Body eine Schleife dar, während die Schleife selbst erst durch 
aufeinander folgende ISR-Aufrufe zustande kommt.

> Dass du durch den Overhead von Interrupts Zeit verlierst ist kaum zu
> vermeiden. Inwieweit sich die Interrupts durch einen anderen Ansatz
> reduzieren lassen musst du selber wissen, dazu liegt mir nicht genug
> Information vor. Die Umkehrung hast du ja selber schon erwähnt.

Ob das wirklich klappen könnte...?

Die main wäre dann eine Endlosschleife um mach_was(). An Ende der 
Schleife würde man auf den Timer schauen und dann wenn noch genug Zeit 
ist, eine Soft-IRQ triggern welche den jetzigen mani-Code mit 
Spiel-Logik, DCF-Auswertung, Terminal-Ausgabe, Taster- und 
RC5-Auswertung, etc. beinhaltet. Aber wie wird die ISR beendet, wenn es 
zeit wird, zurückzukehren? Mir würde da nur ein longjmp ans ISR-Ende 
einfallen. Der setjmp wäre am Anfang der Soft-ISR, und würe beim 
Anspringen direkt zum ISR-Ende gehen. Der longjmp wäre in einer 
Timer-ISR, die über die Soft-ISR wacht.

> Eine rohe Idee will ich noch einbringen, wobei ich mangels Einblick in
> die Aufgabe keine Ahnung habe ob das was bringt: Wenn eine
> Interrupt-Routine ohnehin alles sichert, dann ist der zeitliche
> Unterschied zwischen klassischen Interrupts und Contextswitches in
> zeiteffizienten RTOS-Kernels wie AvrX nicht allzu gross.
>
> Das mag zunächst etwas paradox klingen, denn es kommt im Prinzip etwas
> Overhead hinzu und das reduziert auch nicht den Zeitverlust von
> Interrupts. es könnte aber möglicherweise die Umstellung der
> Arbeitsweise auf deutlich andere Ansätze programmiertechnisch
> erleichtern um so vielleicht die Anzahl Interrupts/Contextswitches zu
> reduzieren. Oder zumindest die verfügbare Rechenzeit auf die vorrangige
> Tätigkeit konzentrieren.

Am wichtigsten ist das Zeichen der Pixel, und das muss in regelmäßigen 
Zeitabständen geschehen. Jitter macht sich bemerkbar durch 
unterschiedlich helle Pixel bzw. unexakt positionierte Pixel. Daher wird 
die Pixelausgabe vor der Berechnung gemacht (main.c:118 bzw. dac.h).

Johann

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Achso, Compiler ist übrigens avr-gcc 3.4.6 mit -Os.

avr-gcc 4.x mach um mindestens 500 Byte größeren Code. IdR sind das 
unnötige Instruktionen; der Code wird auch etwas langsamer als mit 
3.4.6.

Johann

von Stefan Salewski (Gast)


Lesenswert?

>Autor: Johann L. (gjlayde) Benutzerseite
>Datum: 18.07.2009 13:27

>Achso, Compiler ist übrigens avr-gcc 3.4.6 mit -Os.

>avr-gcc 4.x mach um mindestens 500 Byte größeren Code. IdR sind das
>unnötige Instruktionen; der Code wird auch etwas langsamer als mit
>3.4.6.

>Johann

Das Thema wurde hier vor Jahren ausgiebig diskutiert...
Ergebnis war wohl, dass man mit 4.x zumindest ähnlich guten Code wie mit 
3.4.6 bekommen kann, wenn man sich Mühe gibt. Und was heißt schon 4.x, 
4.3 sollte man wohl zumindest verwenden, nächste Woche soll ja 4.4.1 
erscheinen.

Nur das jetzt nicht wieder der Eindruck entsteht, der alte 3.4.6 wäre 
stets die bessere Wahl.

Oder Jörg, was meinst Du?

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Stefan Salewski schrieb:
>>Autor: Johann L. (gjlayde) Benutzerseite
>>Datum: 18.07.2009 13:27
>
>>Achso, Compiler ist übrigens avr-gcc 3.4.6 mit -Os.
>
>>avr-gcc 4.x mach um mindestens 500 Byte größeren Code. IdR sind das
>>unnötige Instruktionen; der Code wird auch etwas langsamer als mit
>>3.4.6.
>
>>Johann
>
> Das Thema wurde hier vor Jahren ausgiebig diskutiert...
> Ergebnis war wohl, dass man mit 4.x zumindest ähnlich guten Code wie mit
> 3.4.6 bekommen kann, wenn man sich Mühe gibt. Und was heißt schon 4.x,
> 4.3 sollte man wohl zumindest verwenden, nächste Woche soll ja 4.4.1
> erscheinen.

Ich hab mehr als 1x avr-gcc 4.x angetestet. Nich nur eine Version und 
nicht nur einen Satz Optionen (-fno-tree-scev-cprop 
-fno-inline-small-functions -fno-move-loop-invariants 
-fno-tree-loop-optimize  -fno-split-wide-types, -morder1, -morder2, ...) 
Ich hab sogar einen "Bastard" aus unterschiedlich erzeugten Objekten 
getestet, wo ich für jedes Object-File, das aus einer Quelle hervorging, 
nur die kleinste Binärversion gelinkt habe. Selbst damit war 3.4.6 
deutlich besser.

Möglicherweise liegt's auch daran, weil ich recht genau weiß wie gcc 
arbeitet und Code schreibe, mit dem er gut klarkommt (Ich mach selber 
gcc-Entwicklung, momentan porte ich gcc 4.3.3 für nen exotischen 32-Bit 
µC).

> Nur das jetzt nicht wieder der Eindruck entsteht, der alte 3.4.6 wäre
> stets die bessere Wahl.

Stets wohl nicht, aber bisher hat er in keinem meiner Projekte bessere 
Arbeit gemacht als 3.4.6, und bei dem vorliegenden Projekt ist nichts 
zu verschenken.

Der neue IRA ab gcc 4.4 bringt in Bezug auf AVR leider Ernüchterung 
(4.4.0, 4.4.1, 4.5.0) jedenfalls was ich so gesehen hab.

avr-gcc ist eben ein Waisenkind wie andere 8-Bit Targets auch. A.K. 
könnte doch bei der avr-gcc-Entwicklung mitmachen. Jedenfalls hab ich 
schon gesehen daß er in avr-gcc reindebuggt fg.

Für das obige ZIP
  http://www.mikrocontroller.net/attachment/54523/morpheus_2009-07-18.zip
ist die erzeugte Codegröße mit gcc 3.4.6 genau 13314 Bytes. Mit
1
make all size
 bzw.
1
make all fsize
 kannst du die Größe einzelner Module/Objekte anzeigen lassen. Ich glaub 
nicht, daß du durch Rumklimpern an 4.x-Optionen da was rausholst. Dabei 
verwende ich noch nichtmal die Killer eeprom_read_block et al. -- aber 
das steht irgendwann zur Speicherung von Systemeinstellungen (oder 
HighScores ;-)) noch bevor...

Johann

von Stefan Salewski (Gast)


Lesenswert?

@Johann L. (gjlayde)
>Möglicherweise liegt's auch daran, weil ich recht genau weiß wie gcc
>arbeitet und Code schreibe, mit dem er gut klarkommt (Ich mach selber
>gcc-Entwicklung, momentan porte ich gcc 4.3.3 für nen exotischen 32-Bit
>µC).

Das wusste ich nicht -- mir fällt eigentlich derzeit nur der Name Jörg 
Wunsch ein, wenn ich an noch aktive Leute in diesem Forum denke, die 
sich etwas mit avr-gcc auskennen. Es gab wohl mal auch andere, aber die 
sind wohl alle von den Dummschwätzern vergrault worden.

Na mal sehen wie lange Du uns erhalten bleibst...

Gruß

Stefan

von (prx) A. K. (prx)


Lesenswert?

gcc 4.4 (in Crossworks 2.0) ist ohnehin so eine Sache. Die ARM Version 
davon hat vor Freigabe wohl auch niemand getestet, jedenfalls nicht in 
den Code reingesehen.

von (prx) A. K. (prx)


Lesenswert?

Johann L. schrieb:

> könnte doch bei der avr-gcc-Entwicklung mitmachen. Jedenfalls hab ich
> schon gesehen daß er in avr-gcc reindebuggt fg.

Eigentlich nicht. Ein paar Bugmeldungen von mir sind drin. Und auch die 
sind nicht alle vor mir, sondern entstammen teilweise dem hiesigen 
Forum.

Du hast ja selber schon gemerkt, dass allerlei De-Optimierungen der 4er 
Versionen bezogen auch AVR eher vom maschinenunabhängigen Teil 
verursacht werden. Da ist recht schwer gegen anzustinken.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> Johann L. schrieb:
>
>> könnte doch bei der avr-gcc-Entwicklung mitmachen. Jedenfalls hab ich
>> schon gesehen daß er in avr-gcc reindebuggt fg.
>
> Eigentlich nicht. Ein paar Bugmeldungen von mir sind drin. Und auch die
> sind nicht alle vor mir, sondern entstammen teilweise dem hiesigen
> Forum.

Ausreden gülden nicht. Beweismittel No 1: ab
    Beitrag "Re: C Code Optimierung für LCD (AVR32)"

> Du hast ja selber schon gemerkt, dass allerlei De-Optimierungen der 4er
> Versionen bezogen auch AVR eher vom maschinenunabhängigen Teil
> verursacht werden. Da ist recht schwer gegen anzustinken.

Das liegt aber auch daran, daß die Leute keine gescheiten Bug-Reports 
machen (Märchen-Code mit "...", keine richtigen Testfälle, etc.)
Erschwert wird die Sachlage bei PRs, die sich auf WinAVR beziehen, weil 
das keine offizielle FSF-Release ist und der avr-gcc "private" Patches 
von Eric enthält (Die nicht in der Mainline sind, weil Eric auch kein 
FSF-Assignment hat).

Wenn eine GCC-Kapriole im Frontend ist und es sich auf einem gängigen 
Target wie i386 nachvollziehen lässt, hat man sehr gute Karten. 
Ansonsten ist es natürlich mühsam, weil man erst man nachweisen muss, 
daß im Backend nicht was an den Kosten oder mit ungünstigen Expandern 
verbockt wurde.

Für avr-gcc 4.4.0 hatte Eric noch nichtmal ne Release gemacht (da er 
Bugs befürchtet), die aber m.E. wichtig wäre, weil damit mehr Leute 
testen und potentielle Probleme berichten würden. IRA hält bestimmt 
einige Überraschungen bereit... Die AVR-Mannen müssten sich eben auch 
öfter zu Wort melden, und avr-gcc-Entwickler gibt's momentan ja 
praktisch keinen. Anatoly maintaint, Eric flickt neue Derivate nach und 
das war's...

Johann

von ISR (Gast)


Lesenswert?

Die ISR hat 7000 Zeilen und Du willst ein paar Taktzyklen im Epilog 
sparen? Das passt nicht mal ansatzweise zusammen. Such' in den 7000 
Zeilen und verschwende nicht unsere Zeit.

von Stefan Salewski (Gast)


Lesenswert?

>Die ISR hat 7000 Zeilen und Du willst ein paar Taktzyklen im Epilog
>sparen? Das passt nicht mal ansatzweise zusammen. Such' in den 7000
>Zeilen und verschwende nicht unsere Zeit.

Johann hat ja nicht geschrieben, dass stets alle 7000 Zeilen ausgeführt 
werden. Ich denke er weiß schon was er tut, und der letzte Teilsatz 
Deiner obigen Aussage trifft wohl eher auf dich zu.

von ISR (Gast)


Lesenswert?

Ha! Deine Naivität möchte ich haben :-) Aber warten wir ab, was der OP 
dazu sagt, denn er war gemeint.

Und ja ne is klar, türlich werden nicht alle ach so 7000 Zeilen 
ausgeführt. Es wird sich schon die eine oder andere Monsterverzweigung 
oder Monsterswitch finden.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

ISR schrieb:
> Die ISR hat 7000 Zeilen und Du willst ein paar Taktzyklen im Epilog
> sparen? Das passt nicht mal ansatzweise zusammen.

Die Anzahl Codezeilen gibt einen ungefähre Vorstellung von dem Aufwand, 
der es wäre, das alles nach Assembler zu portieren, um ein eigenes 
Registerlayout zu implementieren.

Die geschätzen 7000 Zeilen sind natürlich verzweigt, ansonsten wären 
sie kaum in ~500 Ticks abzuhandeln. Die erste Verzweigungsebene ist zB 
ein indirekter Funktionsaufruf, der abhängig vom gewählten Menüpunkt zum 
jeweiligen Handler springt.

Es ging darum evtl. andere Ansätze zu finden, wie zB das Design "auf den 
Kopf" zu stellen wie oben skizziert. Vielleicht hat jemand schonmal 
sowas versucht und gute Erfahrung gemacht, oder ich überseh was 
prinzipielles und es geht nicht durch, oder es wäre viel Arbeit und 
bringt nix.

> Such' in den 7000 Zeilen und verschwende nicht unsere Zeit.

Deine Zeit kannst nur du selber verschwenden, das übernimmt niemand 
sonst für dich. Wenn das Lesen der Beiträge hier für dich eine 
Zeitverschwendung ist -- lass es.

Wenn ich Fragen zur effektiveren Umsetzung dieser 7000 Zeilen hätte 
würde ich danach gefragt und konkreten Code gepostet haben. Ich hab 
immer ein Auge darauf, was avr-gcc so treibt, und wenn er nicht pariert 
wie erwartet, kriegt er eben eins auf die Finger ;-)

Johann

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.