www.mikrocontroller.net

Forum: Compiler & IDEs forschleife: anzahl Takte??


Autor: chrigu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
kann mir jemand sagen wie viele takte EIN Durchlauf einer simplen
for-Schleife hat bzw. wie ich das rausfinden kann?( z.B:
for(i=1;i<100;i++); )
und wie ist das mit einer while schleife?z.B.x=100; while(x--);

Und noch eine frage am rande kann man eine if-bedingung in eine
for-schleife einbauen? z.B. for(i=1;i<100;if(x==3)i++;);

Hoffe ihr könnt mir helfen
 Gruss Chrigu

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die erste Frage lässt sich nur durch Ansehen des vom Compiler erzeugten
Assemblerlistings klären. Welche Compileroption für die Erzeugung eines
kommentierten Assemblerlistings (C-Quelltextzeilen als Kommentare
eingefügt) zuständig ist, wirst Du der Dokumentation entnehmen können.
Das wurde hier aber auch schon gelegentlich besprochen.

Was spricht dagegen, das in der zweiten Frage formulierte Konstrukt
einfach auszuprobieren?

Wenns nicht geht, wird das der Compiler schon sagen.

Autor: chrigu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,
danke:D auf die idee mit dem compilieren hätt ich au ckommen können,
danke!!
Aber nun habe ich in einer vom compiler erzeugten *.lss Datei
gefunden:
....
int x, y=3;
for(x=100;x;)if(y==3)x--;;
  64:  84 e6         ldi  r24, 0x64  ; 100
  66:  90 e0         ldi  r25, 0x00  ; 0
  68:  c2 97         sbiw  r24, 0x32  ; 50
  6a:  f1 f7         brne  .-4        ; 0x68
  6c:  00 c0         rjmp  .+0        ; 0x6e
....
ist das jetzt der asm-codefür dieses Konstrukt? also dauert dies 5
takte?
habe leider null ahnung von asm...
Danke schonmal ;-)

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, das was du da probierst wird nicht ganz funktionieren.
Die Eingangsbedingungen in die for-schleife sind vorbestimmt.
Ein Optimierer kann diese Schleife voll auflösen da er sämtliche
parameter kennt. Oder deutlicher gesagt die ganze Schleife kann
vollständig eliminiert werden.
Solltest du eine delay Routine programmieren wollen, so füge ein nop
ein.
Du willst warten bis y 100mal 3 war. y ändert sich nebenher z.B. aus
einem Interrupt. Ohne das kleine Wörtchen volatile wird das nicht
funktionieren.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ist tatsächlich der Assembler-Code für die for-Schleife. Aber wie
Wolfram schon sagte: Deine Schleife macht anscheinend nicht viel
Sinn... Da y nicht als volatile deklariert ist, wird die if-Abfrage
komplett wegoptimiert. Außerdem macht der Compiler aus der eigentlichen
for-Schleife mit (gewollten) 100 Durchläufen eine mit 2 Durchläufen (x
wird nicht um 1 sondern um 50 dekrementiert). Compilier das ruhig mal
mit ausgeschalteter Optimierung und schau Dir das Ergebnis an. Da kommt
wesentlich mehr Code raus...

Ganz allgemein: Wenn Du anhand der .lss-Datei die Ausführungszeiten
ermitteln willst, musst Du Dir das Instruction Set Manual mal
vornehmen. Da steht für jeden einzelnen Befehl drin, wie viele
Taktzyklen er braucht. Es gibt nämlich auch Befehle, die mehr als einen
Zyklus brauchen (z.B. sbiw braucht zwei) und es gibt Sprung- und
Verzweigungs-Befehle, die je nachdem, ob die Bedingung wahr oder falsch
ist, unterschiedliche Ausführungszeiten haben (z.B. brne).

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Solltest du eine delay Routine programmieren wollen, so füge
> ein nop ein.

Oder nimm gleich die Funktionen aus <util/delay.h>, dort haben
sich andere Leute schon die Mühe gemacht, die Zyklenzahlen
auszuzählen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vor allem haben die auch inline-Assembler verwendet, so daß die
Zyklenzahlen nicht von den Optimierungseinstellungen oder der Version
des Compilers abhängen.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ganz anderer Ansatz: Mit einem Frequenzzähler am laufenden System
ausmessen. Das ist manchmal einfacher als komplexe Assembleropcodes
nachzuschlagen.

int main(void)
{
  while(1)
  {
    port_einschalten();

    /* Messobjekt z.B. */
    delay_funktion(1000);

    port_ausschalten();
  }
}

Die Ausführungszeit ist 1/Frequenz.

Die Messung wird um so genauer, je "enger" sich die Schaltbefehle am
Untersuchungsobjekt befinden. Also ggf. statt Funktionen Makros
benutzen.

Noch ein anderer Ansatz: Manche Debugger/Simulatoren zeigen die
benötigte Zyklenzahl für ein Stück Assemblercode auch an.

Autor: Alex (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
while(1)
  {
    port_einschalten();
    delay_funktion(1000);
    port_ausschalten();
    delay_funktion(1000);
  }

Sonst ist die Pulsweite ein wenig klein :)

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stimmt. Danke!

Typischer Fall von ins Forum tippen und nicht nachdenken. Beim letzten
Mal hatte ich es nämlich so gemacht

  while(1)
  {
    port_toggle();

    /* Messobjekt z.B. */
    delay_funktion(1000);
  }

Autor: chrigu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, danke viel mal!
Ich habe die optimierung mal ausgeschaltet und tatsächlich kam
ordentlich viel mehr code raus.
Damit das ganze nicht so wegoptimiert wird muss ich also die variablen
als volatile deklarierten.
Allerdings ist mir folgendes nicht ganz klar:
> Solltest du eine delay Routine programmieren wollen, so füge
> ein nop ein.
Wo soll ich nop einfügen?? einfach in die Schleife?
for(blabla)
{bla;
nop} ???
Grüsse
Chrigu

Autor: peter dannegger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich verstehe nicht, warum sich Leute immer das Leben unnötig schwer
machen müssen und vielleicht noch umständlich irgendwelche Delays
ausmessen müssen.

Und beim nächsten Quarz oder der nächsten Compilerversion stimmt dann
gar nichts mehr und der Ärger geht von vorne los.


Man kann doch prima einen Timer nehmen und Compiler unabhängig
beliebige Delays für beliebige Quarze bequem vom Präprozessor berechnen
lassen:

http://www.mikrocontroller.net/forum/read-4-84831.html#new


Peter

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter, dort wo du schon warst, müssen andere (ich) erst noch hinkommen
;-) Für einen Anfänger (wie mich) ist das Ausmessen der am schnellsten
erfolgversprechende Weg. Und der Appetit kommt bekanntlich beim
Essen... Zum Glück gibt es dann feine Kochrezepte wie deine "genaue
Sekunde"!

Autor: chrigu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
den Timer könnte ich schon nehmen, habe den timer 0 und 1(mega8)
allerdings schon belegt, möchte nicht noch den letzten auch nehmen
(mühsam):-). Vielleicht nehme ich den am ende doch,
 aber wo muss ich grundsätzlich nop hinschreiben? kann ja auch sonst
mal nützlich sein denke ich.
Danke:)

(PS: ich brauche eigentlich nicht direkt ein delay, würde auf umwegen
aber auch damit gehen.)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man nimmt im Wesentlichen einen Timer, der den "Systemtakt" liefert,
und lässt den dann alle zeitgesteuerten Ereignisse abarbeiten.  Damit
braucht man nicht für jede Verzögerun einen neuen Hardware-Timer.

Der NOP gehört in die Schleife:

_asm_ volatile("nop");

damit diese nicht wegoptimiert werden kann.  Aber s. o., wenn schon
Verzögerung mit Schleifen, nimm besser das, was andere dir schon
vorgearbeitet haben.  Für kurze Verzögerungen (also vor allem solche
im Mikrosekundenbereich) sind delays oft genug vonnöten, weil sich
das Anwerfen eines Timers dann nicht erst lohnt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Für einen Anfänger (wie mich) ist das Ausmessen der am schnellsten
> erfolgversprechende Weg.

Für einen Anfänger ist der erfolgversprechendste Weg Funktionen
zu benutzen, die andere bereits vorgefertigt haben und die
daher auch funktionieren.

In 'delay.h' gibt es eine fix fertige funktionierende
Verzögerungsschleife, wenns denn unbedingt eine Verzögerung
sein soll.

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Für einen Anfänger ist der erfolgversprechendste Weg Funktionen
>zu benutzen, die andere bereits vorgefertigt haben und die
>daher auch funktionieren

aber nur wenn er deren Funktionsweise verstanden hat.
gilt insbesondere für die empfohlenen delayroutinen
Lies bitte die Dokumentation und Einschränkungen genau durch.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.