mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Wie lange dauert ein Prozessschritt?


Autor: Thomas (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

bin Anfänger.
Ich möchte innerhlab eines Programmes (s.ICP_UART_162_01.c) vom Programm 
durchgeführte Berechnungen auf ihren Zeitverbrauch hin messen.

dazu schalte ich vor der Rechnung PINA4 auf 0 und nach der Messung 
wieder auf 1. Das dabei entstehende negative Signal messe ich mit dem 
Oszi.

Habe das Bild angehängt.

Nun die Frage:

Es ist egal, welche Berechnung ich messe, ob

Erg=Erg*100 / 36 oder die Nachfolgende, oder aber alle drei( incl
signal = Faktor*1.000.000 / Erg,

Es kommt immer ein Wert um die 13,84 µs raus.  Habe ich hier einen 
grundsätzlichen Denkfehler?

Würde mich über einen Tipp freuen

Thomas

Autor: X- Rocka (x-rocka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
edit.

Kuck dir mal das Listing / Assembler an, vor allem wenn du nur eine oder 
alle 3 Berechnungen verwendest. Sollte eigentlich bei 3 Berechnungen 
länger dauern.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> Es kommt immer ein Wert um die 13,84 µs raus.

Deine Grafik zeigt aber etwas anderes ...


Gruß

Jobst

Autor: ulrich (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die C Compiler können da einiges Optimieren. Es ist gut möglich das sich 
durch die Umstellung der Faktoren am erzeugten Code nichts ändert. 
Einiger der Faktoren werden auch schon zur Laufzeit zusammengefasst - 
soweit es halt geht.  Ob man 10000 oder 10*10*100 schreibt ist z.B. 
egal.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
....weil ich aus der *.lss Datei nicht schlau werde, hatte ich versucht 
das Problem in der oben beschriebenen Art zu löen. In der assemblerdatei 
kann ich die einzelnen Rechenschritte nicht differenzieren, da ich kein 
assembler kann.

In der assemblerdatei werden auch nicht alle Kommentierungen angezeigt, 
an denen ich mich hätte orientieren können.

Gruß

Thomas

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Jobst

sorry, ich habe das erste Mal mein neues Oszi in Betreib genommen. Habe 
vorher noch nie sowas genutzt. kann sein, dass ich damit vielleicht was 
ganz anderes gemessen hatte?

Gruß
Thomas

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Optimierungen eingeschaltet sind, wird der Compiler die 
Berechnungen nicht zwangsläufig zwischen den Zuweisungen an PORTA 
durchführen. Die Initialisierung von Erg greift auf volatile Variablen 
zu und wird deshalb zwangsläufig vor dem ersten PORTA Zugriff 
abgearbeitet. Die anderen Berechnungen aber kann der Compiler beliebig 
umformen und auch hinter den zweiten PORTA verschieben, es zählt nur das 
Ergebnis signal, das itoa() übergeben wird.

Autor: Jobst M. (jobstens-de)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> @ Jobst
>
> sorry, ich habe das erste Mal mein neues Oszi in Betreib genommen. Habe
> vorher noch nie sowas genutzt. kann sein, dass ich damit vielleicht was
> ganz anderes gemessen hatte?
>
> Gruß
> Thomas

Naja, etwa 180us ...


Gruß

Jobst

Autor: X- Rocka (x-rocka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas B. schrieb:
> Wenn Optimierungen eingeschaltet sind, wird der Compiler die
> Berechnungen nicht zwangsläufig zwischen den Zuweisungen an PORTA
> durchführen. Die Initialisierung von Erg greift auf volatile Variablen
> zu und wird deshalb zwangsläufig vor dem ersten PORTA Zugriff
> abgearbeitet. Die anderen Berechnungen aber kann der Compiler beliebig
> umformen und auch hinter den zweiten PORTA verschieben, es zählt nur das
> Ergebnis signal, das itoa() übergeben wird.

Echt, so wat fieses tun Compiler?!

Autor: Rolf Magnus (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja. Ist nach ISO-C auch völlig ok. Das nennt sich "as-if rule" und 
besagt, daß das Programm nicht exakt das tun muß, was im Code steht, 
sondern daß es reicht, wenn das "observable behavior" gleich ist, und 
das ist definiert über I/O und den Zugriff auf volatile-Variablen. Alles 
andere darf beliebig verändert, umsortiert, zusammengefaßt oder 
wegoptimiert werden.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
An alle:

Vielen dank für Eure Hilfe!
Insbesondere die erklärungen von Andreas B in Hinblick auf das 
Compilerverhalten waren sehr erhellend!

Gruß

Thoms

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus schrieb:
> Ja. Ist nach ISO-C auch völlig ok. Das nennt sich "as-if rule" und
> besagt, daß das Programm nicht exakt das tun muß, was im Code steht,
> sondern daß es reicht, wenn das "observable behavior" gleich ist
Aber das beobachtbare Verhalten ist m.E. anders, wenn der Compiler
aus dem hier:
    PORTA &= ~(1<<PA4); // neg. Peak beginnt
   
    Erg = Erg*100 / 36; 
    Faktor = Erg*65 / 10000;
    signal = Faktor*1000000 / Erg; 

    PORTA |= (1<<PA4); // neg Peak endet
das hier macht:
    PORTA &= ~(1<<PA4); // neg. Peak beginnt
    PORTA |= (1<<PA4);  // neg Peak endet
   
    Erg = Erg*100 / 36; 
    Faktor = Erg*65 / 10000;
    signal = Faktor*1000000 / Erg; 
Das dürfte er ja.

Und wenn es tatsächlich so ist, wie kann ich den Compiler sanft dazu 
zwingen, mir die Beobachtung der Rechenzeit zu ermöglichen? Ist da mit 
Klammern/Blöcken was zu machen?
    PORTA &= ~(1<<PA4); // neg. Peak beginnt
    {   
    Erg = Erg*100 / 36; 
    Faktor = Erg*65 / 10000;
    signal = Faktor*1000000 / Erg; 
    }
    PORTA |= (1<<PA4); // neg Peak endet

Und was ist bei sowas:
void calc() 
{
    Erg = Erg*100 / 36; 
    Faktor = Erg*65 / 10000;
    signal = Faktor*1000000 / Erg; 
}
:
:
    PORTA &= ~(1<<PA4); // neg. Peak beginnt
    calc();
    PORTA |= (1<<PA4); // neg Peak endet
Darf der Compiler das auch umstellen:
void calc() 
{
    Erg = Erg*100 / 36; 
    Faktor = Erg*65 / 10000;
    signal = Faktor*1000000 / Erg; 
}
:
:
    PORTA &= ~(1<<PA4); // neg. Peak beginnt
    PORTA |= (1<<PA4);  // neg Peak endet
    calc();

Oder, um die Frage umzustellen:
(Wie) kann ich denn mit den hier aufgeführten Mitteln (Oszi + Portpin) 
die benötigte Zeit für eine Berechnung ermitteln?

Es hilft ja nichts, alle beteiligten Variablen auf volatile zu setzen, 
das wäre dann ja nicht mehr der Code, den ich eigentlich vermessen 
will...

Autor: Andreas B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Compiler darf auch den Funktionsaufruf umstellen und auch inline 
expandieren. Um es wirklich so mit Port-Pin zu machen, sollte im GCC 
wohl das funktionieren:
int result = 0;     // wird als Dummy verwendet

PORTA &= ~(1<<PA4); // neg. Peak beginnt
asm volatile ("" : "X"(result));
result = calc();
asm volatile ("" : "X"(result));
PORTA |= (1<<PA4);  // neg Peak endet

Damit wird ein Assembler-Befehl eingefügt (tatsächlich nur ein leerer 
String) und dem Compiler gesagt, dass er den nicht wegoptimieren darf. 
Dazu dann wird result darin referenziert, so dass auch da die 
Reihenfolge nicht geändert werden kann.


Eine bessere Möglichkeit auch ohne Oszi dürfte sein, alles in eine 
Funktion zu packen (die das Ergebnis auch zurück gibt, damit halt nicht 
der ganze Inhalt der Funktion wegoptimiert wird) und die in einer 
anderen Datei (um dem Compiler Kenntnisse um Inhalt der Funktion zu 
verweigern) in einer Schleife 10000 mal oder so aufzurufen.

Die Zeit der ganzen Schleife geteilt durch die Durchläufe gibt dann die 
Laufzeit der Funktion (+ Aufruf + Schleife). Man kann das ganze noch mal 
mit einer leeren Funktion machen, dann sollte man die Zeit für Aufruf 
und Schleife haben und kann die vom ersten Wert abziehen.

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.