Na ihr,
Die Verpackung verspricht ja im Normalfall viel mehr als wirklich
geleistet wird.
Heute habe ich mal aus reiner Neugierde ausgetestet, ob das auch für
einen AVR(oder bzw den verwendeten Quarz) zutrifft.
Folgendes Programm soll einfach zählen und nach jedem Zählvorgang eine
Led ein/ausschalten:
1
...
2
longi;
3
while(1){
4
for(i=0;i<=6000000;i++){}
5
if(PINC.0==1)PORTC.0=0;
6
elsePORTC.0=1;
7
};
8
...
Der "geht mir aufn Sac*"-Teil:
Diese Schleife sollte wie man sieht bis 6000000(6Millionen) zählen.
Dazu(also für eine Periode) benötigt mein ATMEGA32 mit 16MHZ Quarz etwa
20 sekunden.
-> Rechnen: 6000000/20=300000HZ=300KHZ
-> lol, nen ATMEGA mit 16MHZ-Quarz kann nicht schneller als mit 300KHZ
zählen??
Das ist wohl oder übel ein Verhältniss von 1/53.
mfg Renato
achso klar, eine 32bit addition, sowie der schleifen counter etc
brauchen auch nur 1nen takt oder wie ? ;)
schau die den asm code an und man siehe und staune was da für ein
monster rauskommt ;)
Hab auch ne 8Bit und 16Bit Addition versucht. Die Unterschiede liegen
unterhalb des Sekundenbereichs.
Hab mir fast gedacht dass jetzt gleich Assembler erwähnt wird. :D
Na dann lern ich jetzt mal Assembler Programmieren.(Dieser Schritt
musste ja irgendwann mal kommen ^^)
Schon mal irgendwer ausprobiert wie schnell man mit Assembler nen
Counter hinkriegt?(Also verhältnis zwischen Clock und tatsächlicher
Zählgeschwindigkeit)
mfg
>Schon mal irgendwer ausprobiert wie schnell man mit Assembler nen>Counter hinkriegt?
Nein? Counter sollte man generell vermeiden.
Es kommt immer nur Schrott dabei raus. Volldepp!
Ein normaler 8 bit Counter braucht inclusive Auswerten der
Abbruchbedingung 3 Takte Assembler auf einem AVR.
Es gibt in C eine äquivalente Funktion:
void _delay_loop_1 (uint8_t __count)
In 16 Bit benötigt das 5 Takte, in C entsprechend:
void _delay_loop_2 (uint16_t __count)
Grüße,
Peter
>Nein? Counter sollte man generell vermeiden.>Es kommt immer nur Schrott dabei raus. Volldepp!
Vermeiden? Was soll ich denn Vermeiden?
Ich will nur sehen wie schnell der Zählen tut und wenn möglich ne
schnellere Methode als meine finden.
Du verstehst wohl den Sinn des Topics nicht? :)
Renato P. schrieb:
>>Nein? Counter sollte man generell vermeiden.>>Es kommt immer nur Schrott dabei raus. Volldepp!>> Vermeiden? Was soll ich denn Vermeiden?> Ich will nur sehen wie schnell der Zählen tut und wenn möglich ne> schnellere Methode als meine finden.> Du verstehst wohl den Sinn des Topics nicht? :)
und du nicht die funktionsweise von mcu, compiler & co...
nachdem du dich durch die tuts hier durchgearbeitet hast reden wir
weiter ;)
Renato P. schrieb:
> Ich will nur sehen wie schnell der Zählen tut und wenn möglich ne> schnellere Methode als meine finden.
Und was soll das für einen Sinn haben?
Wenn Du schnell zählen willst, nimm nen Timer.
Dann kannst Du nebenbei noch andere Sachen machen.
53 Zyklen kann hinkommen, immerhin hast Du ja die Optimierung
ausgeschaltet. Mit Optimierung wird diese Schleife nämlich in 0µs
ausgeführt.
Und kein 8-Bitter macht 32Bit-Operationen in einem Takt, er muß sie aus
mehreren 8Bit-Operationen zusammensetzen.
> Du verstehst wohl den Sinn des Topics nicht? :)
Den versteht wohl keiner.
Peter
Andi D. schrieb:
> Renato P. schrieb:>>>Nein? Counter sollte man generell vermeiden.>>>Es kommt immer nur Schrott dabei raus. Volldepp!>>>> Vermeiden? Was soll ich denn Vermeiden?>> Ich will nur sehen wie schnell der Zählen tut und wenn möglich ne>> schnellere Methode als meine finden.>> Du verstehst wohl den Sinn des Topics nicht? :)>> und du nicht die funktionsweise von mcu, compiler & co...
Jo, hab mich nicht besonders mit der Funktionsweise beschäftigt.
Ich habe mich ausserdem nicht mit der Funktionsweise eines PC's
beschäftigt.
Für meine Anwendungen war/ist das (noch) nicht notwendig.
>nachdem du dich durch die tuts hier durchgearbeitet hast reden wir>weiter ;)
Jo mach ma ;)
Peter Dannegger schrieb:
> Renato P. schrieb:>> Ich will nur sehen wie schnell der Zählen tut und wenn möglich ne>> schnellere Methode als meine finden.>> Und was soll das für einen Sinn haben?
Tja das ist eine wirklich triviale Frage!
Ich teste und lerne!
Hast du schon mal eine Led aus/eingeschaltet? Wahrscheinlich ja! Hat das
etwa als selbstständige Funktion einen Sinn(ausser wenns mal dunkel is
;))?
Man entdeckt Funktionen, die man später zu einem Sinnvollen Projekt
kombiniert.
Renato P. schrieb:
> Ich teste und lerne!
Trial & Error ist keine gute Lernmethode.
Man wiederholt nur alle die Fehler, die andere längst gemacht haben.
Deutlich effektiver ist es, sich Tutorials, Examples, FAQs, Lib-Manuals
usw. anzusehen.
Dann fällt einem z.B. beim AVR-GCC eine delay.h auf.
Die macht genau das, was Du willst und auf den Takt genau.
Scheinbar sind bei vielen C-Installation die Include-, Doc- und
Example-Verzeichnisse gegen auslesen geschützt und nur mit
Administratorrechten einsehbar.
Peter
>-> lol, nen ATMEGA mit 16MHZ-Quarz kann nicht schneller als mit 300KHZ>zählen??>Das ist wohl oder übel ein Verhältniss von 1/53.
Was hast Du denn erwartet? 1/10? 1/2?
>lol, nen ATMEGA mit 16MHZ-Quarz kann nicht schneller als mit 300KHZ>zählen??
Selber lol. Er kann natürlich mit 16MHZ zählen, wenn man ihn richtig
programmiert. Aber dazu muss man natürlich erstmal das Datenblatt lesen
um überhaupt zu wissen was man tun muss. Von nichts kommt halt nichts.
Herbert schrieb:
>>lol, nen ATMEGA mit 16MHZ-Quarz kann nicht schneller als mit 300KHZ>>zählen??>> Selber lol. Er kann natürlich mit 16MHZ zählen, wenn man ihn richtig> programmiert. Aber dazu muss man natürlich erstmal das Datenblatt lesen> um überhaupt zu wissen was man tun muss. Von nichts kommt halt nichts.
Jo da hab ich mich falsch ausgedrückt. Das war eher auf das zählen
mittels C-Programm bezogen. Natürlich kann ders schneller wenn man weiß
wie.
>-> lol, nen ATMEGA mit 16MHZ-Quarz kann nicht schneller als mit 300KHZ>zählen??>Das ist wohl oder übel ein Verhältniss von 1/53.
Was hast Du denn erwartet? 1/10? 1/2?
Unter C hab ich mir erhofft dass ich zumindest 1/10 hinkrieg ^^
Renato P. schrieb:
> Unter C hab ich mir erhofft dass ich zumindest 1/10 hinkrieg ^^
Schalte den Optimizer ein.
Wie PeDa weiter oben schon gezeigt hat kommt man auf ca. 1/5. Also rund
3.2Mhz
Für 32Bit-Arithmetik ist das gar kein so schlechtes Ergebnis für einen
C-Compiler.
>Unter C hab ich mir erhofft dass ich zumindest 1/10 hinkrieg ^^
auf welcher grundlage hast du denn gehofft?
wie ein prozessor funktioniert ist besonders bei so zeitkritischen
sachen interessant und sollte unbedingt als grundwissen beim
µC-programmieren vorhanden sein.
besonders wenn ich mit der ausführungsgeschwindigkeit in den bereich der
taktfrequenz des prozessors komme (ich sag mal über 1/100 der
taktfrequenz ) wird es wichtig für welche befehle wieviel tacktzyklen
gebraucht werden und wie man da optimieren kann etc.
der simulator gibt einem da einen ganz guten eindruck, der zählt einem
nämlich die tacktzyklen vor. und dort kann man auch nach belieben die
ganze geschichte in assambler bestaunen.
Hallo,
Karl heinz Buchegger schrieb:
> Wie PeDa weiter oben schon gezeigt hat kommt man auf ca. 1/5. Also rund> 3.2Mhz>> Für 32Bit-Arithmetik ist das gar kein so schlechtes Ergebnis für einen> C-Compiler.
Kann ich nur zustimmen. Ich bin eigentlich recht positiv überrascht vom
GGC.
Einige Sachen sollte man aber nicht machen, z.B.
uint64_t test = 1;
test = test << 1;
;-))
Gruß aus Berlin
Michael
Hi!
Diskussion um Compileroptimierung hin oder her,
a) ich verstehe den zweck nicht, wozu man so einen zähler als Schleife
überhaupt sinnvoll einsetzen soll (ausser delay und dabei wäre die
zaehlgeschwindigkeit sowieso völlig egal)
b) will mir nicht in den kopp, wieso man die Ausführungsgeschwindigkeit
eines codes MESSEN muss, wenn alle Faktoren bekannt sind (Taktfrequenz
und benötigte Taktzyklen für die einzelnen Befehle). Das hat man sogar
mit Taschenrechner suchen schneller ausgerechnet als der Lötkolben zum
heizen braucht.
Aber ansonsten recht amüsant der Thread hier :)
Gruss, Malte
Malte Bayer schrieb:
> Diskussion um Compileroptimierung hin oder her,> a) ich verstehe den zweck nicht, wozu man so einen zähler als Schleife> überhaupt sinnvoll einsetzen soll (ausser delay und dabei wäre die> zaehlgeschwindigkeit sowieso völlig egal)
Naja ich wollte nur allgemein mal wissen wie schnell der µC die
C-Befehle abarbeitet. Das Beispiel mit dem Zähler is mir dazu rein
zufällig als erstes eingefallen.
Es ist ja allgemein bekannt das Assembler schneller is als C, nur um
wieviel hab ich noch nie irgendwo gelesen.
Der enorme Geschwindigkeitsverlust bei meinem Programm hat mich total
verblüfft und somit hab ich mal einfach ein Topic aufgemacht.
Und was passiert als erstes? Na klar, jemand schnauzt mich an, weil er
denkt ich will nen Timer oder ne delay proggen. ^^
sorry deswegen...
> b) will mir nicht in den kopp, wieso man die Ausführungsgeschwindigkeit> eines codes MESSEN muss, wenn alle Faktoren bekannt sind (Taktfrequenz> und benötigte Taktzyklen für die einzelnen Befehle). Das hat man sogar> mit Taschenrechner suchen schneller ausgerechnet als der Lötkolben zum> heizen braucht.
Ach, für C-Befehle gibts auch irgendwo die Zyklenzeit-Liste?(danke, ich
schau gleich mal nach deswegen). Ich bin wohl Totalnoob...
Auf dem Datenblatt sah ich immer nur die Assembler-Zyklenzeiten und aus
der Schule kenn ich auch nur die Assembler-Zyklenzeit-Rechnungen.
> Aber ansonsten recht amüsant der Thread hier :)
Na das is schön zu hören :P :)
Karl heinz Buchegger schrieb:
> Schalte den Optimizer ein.
Tut man das mit AVR-Studio?
Sam schrieb:
> der simulator gibt einem da einen ganz guten eindruck,
Das tut man dann wohl auch im AVR-Studio?
Jo, dat sind dumme Fragen(ich verwende CodeVisionAVR, vielleicht
deshalb).
Renato P. schrieb:
> Naja ich wollte nur allgemein mal wissen wie schnell der µC die> C-Befehle abarbeitet.
Der arbeitet die überhaupt nicht ab.
Sondern der C-Compiler übersetzt die 'C-Befehle' in Maschinensprache (im
weitesten Sinne ist es genau das was du programmierst, wenn du Assembler
programmierst)
> Es ist ja allgemein bekannt das Assembler schneller is als C, nur um> wieviel hab ich noch nie irgendwo gelesen.
Nein, das ist nicht Allgemein bekannt.
Auf vielen Architekturen ist es mitlerweile so, dass der C-Compiler in
der Lage ist, mindestens 80% aller Assembler-Programmierer bei
durchschnittlichen Programmen zu schlagen.
> Der enorme Geschwindigkeitsverlust bei meinem Programm hat mich total> verblüfft und somit hab ich mal einfach ein Topic aufgemacht.
Der enorme Geschwindigkeitsverlust resultiert daraus, dass du mit deinem
Werkzeug, dem C-Compiler, noch nicht umgehen kannst. Du hast ihn ganz
einfach 'mit angezogener Handbremse' arbeiten lassen. Da fährt dann auch
ein Ferrari nicht schneller als 30km/h
> Ach, für C-Befehle gibts auch irgendwo die Zyklenzeit-Liste?
Nein, die gibt es nicht.
Es hängt immer davon ab, wie der Compiler bestimmte Konstrukte umsetzt.
Und das wiederrum hängt von vielen Faktoren ab.
Hi Renato,
Karl trifft es auf den Punkt,
damit jetzt vielleicht alle Klarheiten beseitigt werden:
Der AVR uC arbeitet die befehle die er versteht (diese sind im
Datenblatt ersichtlich) ab.
Für das Ausführen eines jeden Befehls benötigt er eine Gewisse Menge
Taktzyklen (für die meisten Befehle einen, aber auch zb mal zwei takte
für einen befehl).
Das hat erstmal garnichts mit der verwendeten Programmiersprache zu tun.
In deinem Ursprungspost vermittelst du mir den Eindruck, als ob du davon
ausgehst, dass eine Zählschleife ohne weiteren Inhalt aus einem Befehl
bestünde.
A bissl naiv. Für dich sieht es in C so aus, da es ja nur das for()
konstrukt ist. Der Controller muss aber viel mehr tun:
- zähler addieren (und das nicht nur 1x, da er nur mit 8bit arbeitet)
- vergleichen ob das schleifenende erreicht ist
- schleifensprung
Meine orredner haben dir das ja bereits am entsprechenden Assemblercode
versucht zu erklären.
Es gibt deshalb keine Tabelle mit Befehlszeiten für C-Befehle, weil die
Compiler alle unterschiedliche Befehlskonstrukte für die Controller
daraus produzieren. Zudem hängt das ja auch noch von dem verwendeten
Controller ab.
So zum beispiel können manche AVR hardwareseitige Multiplikation, können
sie dies nicht, so müssen viel mehr Taktzyklen aufgewendet werden um die
Multiplikation auf herkömmlichen Weg zu berechnen.
Was du dir also ganz klar vor Augen halten musst ist: ZÄHLEN kann ein
AVR eine 8bit Zahl mit fOSC/2.
Nämlich
1
Loop:
2
INC r16
3
RJMP Loop
Dabei benötigt das Erhöhen und der Rücksprung jeweils einen Taktzyklus.
Das ganze natürlich wenn du den Zähler auch so programmierst.
Ich kann mir gut vorstellen, dass aus
1
for(i=0;i<=255;i++){}
etwas ähnlich Schlankes wird (ich weiss es nicht genau, weil ich avr
"nur" in assembler programmiere). Logischerweise nicht obiges
Assemblerbeispiel, weil dies ja eine Endlosschleife darstellt.
JS says: "Klar soweit?"
Gruss, Malte
Malte Bayer schrieb:
> Ich kann mir gut vorstellen, dass aus>
1
for(i=0;i<=255;i++){}
> etwas ähnlich Schlankes wird (ich weiss es nicht genau, weil ich avr> "nur" in assembler programmiere).
Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen
pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen
Codeausschnitt einfüge).
Dat ist ja was mich wundert. Ich ging beim programmieren der Schleife
davon aus, dass der höchstens 10 Taktzyklen für einen Zähldurchgang
braucht, aber weit über 40 für eine einfache for-Schleife fand ich
heftig(ich bin aber auch nen bisschen noob in Sachen Taktzyklen).
Klar verlangsamt die while Schleife das ein bisschen. Aber schau mal:
Die While Schleife fängt an, dann sollte die for-Schleife in Ruhe(sie
tut ja nix anderes als zu zählen) bis 6Millionen zählen können und dann
schaltet er den Port um.
Das währen 6Millionen Zählvorgänge, dann 2if's und 1while, dann wieder
6Millionen Zählvorgänge.
Die while-Schleife und die ifs Scheinen mir da vernächlässigbar
klein(sind ja nur 6Befehle die nach den 6Millionen Befehlen kommen).
-> Ich komm halt zum Schluss, dass diese 50 Taktzyklen die der µC bei
mir pro Zählererhöhung gebraucht hat, fast allein an der for-Schleife
liegen
und ps: long in int umgewandelt erhöht die Schleife nur um
milisekunden(habs probiert).
Verstehst was ich meine? Also kurz nochmal heißt das folgendes:
1
for(i=0;i<=1;i++){}//also i um 1 erhöhen
Diese Schleife würde 52Taktzyklen verbraten.
Hingegen:
1
INC r16
nur 1 Taktzyklus
Ich mit meinem ungeschulten Auge finde das schon heftig...
Malte Bayer schrieb:
> In deinem Ursprungspost vermittelst du mir den Eindruck, als ob du davon> ausgehst, dass eine Zählschleife ohne weiteren Inhalt aus einem Befehl> bestünde.
jo sorry, is hin und wieder gar nicht so leicht seine Problemstellung zu
schildern.
@ Renato P.
> Ich schreib wieder mal Stuss.
so falsch war es nicht, man kann ja auch die schleife optimierne.
Wenn man bis 10 Zählen möchte geht das dann so
INC r16
INC r16
INC r16
INC r16
INC r16
INC r16
INC r16
INC r16
INC r16
INC r16
schneller wird es kaum gehen, auch wenn es so kaum sinn macht.
Um den ganzen schmarren mal hier ein wenig Sinn einzuhauchen. Folgendes
Testprogramm (Nach Fehlerkorrektur aus dem Ursprungspost übernommen).
EDIT: Argh, hab mich natürlich prompt vertan. Kleinen moment noch fürs
neue Programm...
Mit folgenden Einstellung braucht die For-Schleife für einen Durchlauf
37 Takte:
avr-gcc -mmcu=atmega644 -Wall -gdwarf-2 -std=gnu99
-DF_CPU=1000000UL -O0 -funsigned-char -funsigned-bitfields -fpack-struct
-fshort-enums -MD -MP -MT test.o -MF dep/test.o.d -c ../test.c
Optimierung ausgeschaltet.
Der Code sieht mehr oder weniger grausam aus (Ich poste nur die for
Schleife):
Renato P. schrieb:
> Malte Bayer schrieb:>> Ich kann mir gut vorstellen, dass aus>>
1
for(i=0;i<=255;i++){}
>> etwas ähnlich Schlankes wird (ich weiss es nicht genau, weil ich avr>> "nur" in assembler programmiere).>> Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen> pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen> Codeausschnitt einfüge).
Wie kommst du denn auf diesen Blödsinn?
Bei Kommandozeile:
avr-gcc -mmcu=atmega644 -Wall -std=gnu99 -DF_CPU=1000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD
-MP -MT test.o -MF dep/test.o.d -c ../test.c
Ich hab mal die Debugsachen rausgeschmissen, die haben ohnehin keinen
Sinn mehr ergeben bei so guter Optimierung.
Renato P. schrieb:
> Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen> pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen> Codeausschnitt einfüge).
Schalt halt endlich mal den Optimierer ein du Held!
Danke für die Posts Leute. Hat sehr geholfen :)
Da ich eure AVRGCC-Codes gleich ausprobieren wollte, hab ich jetzt mal
AVR-Studio heruntergeladen.
Es stimmt, es geht nun 3 mal schneller als vorher.
:D Nur wieso das so ist, hab ich keinen Dunst.
2 eigentlich völlig identische Codes:
1
// AVRGCC mit AVRStudio //CodeVisionAVR's Compiler
Der linke 4 mal schneller :D
Wenn mir den Grund hierfür auch nochmal einer erklären kann, dann bin
ich Glücklich ;)
Arbeitet hier überhaupt einer mit CodeVisionAVR? Vielleicht sollt ich ja
nen umstieg auf AVRStudio wagen.
Simon K. schrieb:
> Renato P. schrieb:>> Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen>> pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen>> Codeausschnitt einfüge).>> Schalt halt endlich mal den Optimierer ein du Held!
Meine IDE erkennt den Befehl asm volatile(""); nicht.
Renato P. schrieb:
> Wenn mir den Grund hierfür auch nochmal einer erklären kann, dann bin> ich Glücklich ;)
Der wahrscheinliche Grund dafür wurde dir jetzt schon ein paar mal
gesagt:
Es hängt davon ab, welche Einstellung du für den Optimizer hast.
Je nachdem wie agressiv der Optimizer optimieren darf, kommt
unterschiedlicher Code heraus.
Renato P. schrieb:
> Simon K. schrieb:>> Renato P. schrieb:>>> Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen>>> pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen>>> Codeausschnitt einfüge).>>>> Schalt halt endlich mal den Optimierer ein du Held!>> Meine IDE erkennt den Befehl asm volatile(""); nicht.
Deiner IDE ist das "asm volatile("");" aber sowas von egal.
Dir fehlt es hinten und vorne an Grundlagen und trotzdem stellst du dich
hier hin und ziehst über Compiler her? Dein Selbstvertrauen möchte ich
haben! Schon mal eine Karriere in der Poltik oder als Konzernmanager ins
Auge gefasst?
@renato
du solltest versuchen zu begreifen was eine höhere programmiersprache
ist.
C ist eine höhere Programmiersprache.
Assembler ist eine "niedere"
Assemblerbefehle stehen immer für einen maschinenbefehl, die der
Prozessor versteht, man spricht schon mit dem Ausdruck, den der
prozessor versteht ... da müssen dann nur das Wort (MOV RJMP etc) durch
das byte, welches diesen befehl für den Prozessor darstellt ausgetauscht
werden ... fertig.
C-Befehle und Programme versteht der Prozessor nicht. Deswegen müssen
C-Programme erst von einem Compiler übersetzt werden, einige C-Befehle
werden in eine ganze reihe von maschinenbefehlen übersetzt.
besonders wenn es sich um datentypen handelt, die größer sind als die
register des Prozessors, braucht der plötzlich viel mehr Anweisungen,
als man annehmen würde.
die kleinen AVR's haben nur 8bit große Register ... um eine 8 bit zahl
zu inkrementieren braucht er die zahl blos aus dem ram (wozu er eine 16
bit adresse in die adressregister schreiben muss etc) in ein register
legen um 1 erhöhen und zurück in den ram schreiben ...
einige compiler optimieren aber auch indem sie die 8 bit variable gleich
im register lassen und gar nicht im ram ablegen.
bei einer 32 oder 64 bit zahl aber wahrscheinlich nicht. denn da braucht
der prozessor ja 4 oder 8 8bit-register.
deswegen werden um eine 64 bit zahl um eins zu erhöhen erst die
niedriegsten 8 bit aus dem ram in ein register geschrieben um eins
erhöht und wieder zurückgeschrieben, gab es nun einen übertrag auf die
nächsten 8 bit (255 -> 256) dann muss er die nächsten 8 bit aus dem ram
holen usw.
Wie du siehst artet dann so ein einfaches Inkrement in eine ziemliche
Arbeit für den Prozessor aus.
Deswegen sollte man schon aus Gründen der effizienten Programmierung auf
solch große Datentypen verzichten. Damit sind Aufgabengebiete wie das
bis-6-Millionen-Zählen alles andere als performant.
Renato P. schrieb:
> Arbeitet hier überhaupt einer mit CodeVisionAVR? Vielleicht sollt ich ja> nen umstieg auf AVRStudio wagen.
Zumindest erheblich weniger als mit dem AVR-GCC (WINAVR, AVRStudio).
Sachen, die nicht im C-Standard festgelegt sind, behandelt jeder
Compiler unterschiedlich, z.B. Inline-Assembler, Interrupthandler.
Und die Compileroptionen (Optimierungs-Level) werden warscheinlich auch
anders eingestellt.
Daher kannst Du die AVR-GCC Tips nicht wörtlich übernehmen, sondern nur
sinngemäß.
Ich benutze auch den AVR-GCC. Da muß man sich nicht mit irgendwelchem
Lizenzgeraffel rumärgern, wenn man an mehreren PCs arbeitet.
Peter
Karl heinz Buchegger schrieb:
> Renato P. schrieb:>> Simon K. schrieb:>>> Renato P. schrieb:>>>> Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen>>>> pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen>>>> Codeausschnitt einfüge).>>>>>> Schalt halt endlich mal den Optimierer ein du Held!>>>> Meine IDE erkennt den Befehl asm volatile(""); nicht.>> Deiner IDE ist das "asm volatile("");" aber sowas von egal.
Mir kommt vor ich hab vorher grad wo gelesen, dass dieses asm
volatile(""); die optimierung sein soll.
Hab ich mich wohl verlesen oder?
Renato P. schrieb:
> Karl heinz Buchegger schrieb:>> Renato P. schrieb:>>> Simon K. schrieb:>>>> Renato P. schrieb:>>>>> Diese Schleife wird denk ich mal ziemlich sicher auch mehr 40 Taktzyklen>>>>> pro Zählererhöhung brauchen(zumindest wenn ichs in meinen obigen>>>>> Codeausschnitt einfüge).>>>>>>>> Schalt halt endlich mal den Optimierer ein du Held!>>>>>> Meine IDE erkennt den Befehl asm volatile(""); nicht.>>>> Deiner IDE ist das "asm volatile("");" aber sowas von egal.>> Mir kommt vor ich hab vorher grad wo gelesen, dass dieses asm> volatile(""); die optimierung sein soll.> Hab ich mich wohl verlesen oder?
Gaaaaaaaanz von vorne.
Wenn dein Compiler sich einen C-Quellcode vornimmt, dann kann er den
ziemlich naiv übersetzen.
zb übersetzt er
1
i=5;
2
i=7;
zu
1
lade ein Register mit dem Wert 5
2
Speichere den Reigsterinhalt im Speicher ab, wo die Variable i liegt
3
lade ein Register mit dem Wert 7
4
Speichere den Reigsterinhalt im Speicher ab, wo die Variable i liegt
ziemlich offensichtlich, dass der ganze Teil mit laden von 5 und
speichern unsinnig ist, da diese 5 sowieso mit einer 7 überschrieben
werden.
Nun, das hilft dem Compiler aber nichts. Der Programmierer hat das so
geschrieben und dieses Geschriebene ist für den Compiler erst mal
Gesetz.
Es sei denn der Programmierer erlaubt dem Compiler zu optimieren. Die
Datenflussanalyse findet raus, dass diese erste Zuweisung für die Katz
ist und schmeisst sie ganz einfach raus.
Das entstehende Programm ist damit zwar auf Detailebene nicht mehr
identisch mit dem was der Programmierer geschrieben hat, aber im
Endeffekt ändert sich nichts. Wenn die komplette Sequenz durchgelaufen
ist, ist das Endergebnis vom ursprünglichen Endergebnis nicht zu
unterscheiden.
Und so wie es hier eine ziemlich offensichtiche Optimierung gibt, gibt
es noch eine Unzahl anderer möglicher Optimierungen die letztendlich
dazu führen, dass das Programm entweder schneller läuft oder weniger
Platz benötigt oder beides gleichzeitig. Allen gemeinsam ist allerdings,
dass das entstehende Programm nicht mehr ein 1:1 Abbild dessen ist, was
der Programmierer geschrieben hat. Es verhält sich nur noch gleich, aber
die 1:1 Entsprechung auf Quellcode-Ebene ist verschwunden.
Dazu muss dem Compiler aber erlaubt werden zu optimieren. Und man
erlaubt ihm dieses, indem man ein Schalter umlegt. Dieser Schalter ist
ein Commandline-switch oder es findet sich irgendwo in deiner IDE eine
entsprechende Checkbox oder sonstige Einstellung dafür