Forum: Mikrocontroller und Digitale Elektronik for schleife


von Robert (Gast)


Lesenswert?

Hi,
bis heute bin ich davon ausgegangen das ich hiermit:

for(x=0;x<=500;x++){
 for(x=0;x<=30000;x++){
 }
}

bei einem ATMEGA mit 16 MHz Taktfrequenz ca 1 Sekunde Verzögerung habe.
Es sind aber ca 6 Sekunden.
Bitte klärt mich auf ;-)

Robert

von Robert (Gast)


Lesenswert?

ups in der inneren schleife muss natürlich y oder so statt x stehen.

von Peter D. (peda)


Lesenswert?

"Bitte klärt mich auf ;-)"

Es kann schlichtweg alles passieren, völlig abhängig von Variablentyp,
Compilerversion und Optimierungslevel.

Daher ist sowas einfach nur sauschlechter Programmierstil (nicht
portabel, nicht reproduzierbar).

Entweder man nimmt die Delay-Funktion oder einen Timer, alles andere
ist reiner Zufall.


Peter

von ---- (Gast)


Lesenswert?

Naja, weil die "Verwaltung" der Schleife auch Zeit braucht
(Sprungbefehl, Vergleiche und Inkrementieren der Wortvariable x und y)

----, (QuadDash).

von crazy horse (Gast)


Lesenswert?

das liegt weniger an der Verwaltung der Schleife (aber auch).
Du steckst einfach nicht dahinter, wie der Compiler das umsetzt. Geht
damit los, wo die Variablen abgelegt werden (liegen sie in Registern,
ist der Kram deutlich schneller als im RAM), ein anderer Compiler (oder
auch nur eine neuere Version des selben Conmpilers) bringen völlig
andere Ergebnisse, ebenso die Optimierungseinstellungen.
Fazit: Finger weg von solchem Krimskrams.
In Assembler kann man es in der Art machen, in einer Hochsprache nicht.

von pücksen (Gast)


Lesenswert?

nunja, also mit 16MHz macht man 16 millionen Cycles.
Das was du machst, sind 15 millionen schleifendurchgänge einer
For-Schleife in C.
Und das Abarbeiten einer C-Instruktion dieser Gattung dauert mehr als
nur einen Takt.

Was ein wenig mehr deine Rechnung aufgehen lassen würde, wär folgender
asm code:
(natürlich müsstest du den code noch an deine Umgebung anpassen)

mov reg1, 16000000 ;(24 bits sind da ausreichend)
loop0:
inc reg1
xor reg1, x  ;setzt zero-flag, wenn reg1 und x gleich sind
jnz loop0    ;springt zu loop0, wenn zero-flag nicht gesetzt ist

Nun addierst du die Anzahl der benötigten Taktzyklen der einzelnen
Instruktionen
inc [reg]
xor [reg], const
jnz (bedingter Sprungbefehl)
zusammen.
16000000 geteilt durch diese Zahl ist x.

Wenn das ganze nun 5 Taktzyklen braucht, läuft die Schleife 3200000 mal
durch. Und das in ziemlich genau einer Sekunde.
sorry für den schlechten code, hab noch nie einen atmel programmiert :)

von pücksen (Gast)


Lesenswert?

naah, sorry, reg1 muss natürlich auf 0 initalisiert werden ;)

von Robert (Gast)


Lesenswert?

war dann wohl ein denkfehler dass von asm zu übertragen.

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.