Forum: Compiler & IDEs Ausführungszeit (Zyklen) ermitteln?


von Stefan R. (Gast)


Lesenswert?

Hallo,

gibt es eigentlich eine Möglichkeit, sich nach dem Kompilieren einen 
Überblick über die Ausführungszeiten eines Programms geben zu lassen? 
Die Dateien .lss und .lst sind ja schon sehr informativ, allerdings 
würde ich gern auch eben Informationen über das Timing haben—im Sinne 
von: Anzahl Zyklen pro Maschinenbefehl und am besten sogar noch nach 
C-Kommandos zusammengefasst, wie das ja schon in der .lss mit der 
Zuordnung von C zu Maschinencode zu sehen ist. Theoretisch wäre das ja 
möglich, aber wie geht das konkret? Hat jemand eine Idee?

Verwendete Software:
CrossPack mit GCC 4.3.3

Stefan

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Stefan R. schrieb:
> Hallo,
>
> gibt es eigentlich eine Möglichkeit, sich nach dem Kompilieren einen
> Überblick über die Ausführungszeiten eines Programms geben zu lassen?

Nennt sich "Statische Analyse", ist aber alles andere als trivial, vor 
allem wenn man möglichst kleine obere Schranken für die WCET (Worst Code 
Execution Time) benötigt. Eine Simulation liefert immer nur untere 
Schranken für die WCET.

> würde ich gern auch eben Informationen über das Timing haben—im Sinne
> von: Anzahl Zyklen pro Maschinenbefehl

Siehe Manual zu AVR-Instruktionen

> und am besten sogar noch nach C-Kommandos zusammengefasst,

Das ist nicht möglich, da markttaugliche C-Compiler schon seit 
mindestens 20 Jahren nicht mehr nach dem Prinzip eines Makro-Assemblers 
functionieren.
D.h. je nach Kontext sieht deine "i = i + 1" komplett anders aus.

: Bearbeitet durch Admin
von Uwe (de0508)


Lesenswert?

Hallo Stefan,

ich habe mir für einen atMega32 einige Routinen geschrieben die einen 
Timer1 (16Bit) mit Prescaler 1 verwenden.
In der ISR(TIMER1_OVF_vect) wird noch mit einem 16Bit Softwarezähler bei 
jedem 65536-ten Durchlauf um 1 erhöht. Eine Bereichsüberlauf wird nicht 
abgefangen.

Ein paar Hilfsfunktionen und ein Macro steuern dann den Messablauf:
1
extern void  init_t1_timer( void );
2
extern void  start_t1_counter( void );
3
extern uint32_t  read_t1_counter( void );
4
#define  stop_t1_counter()  sbit(SFIOR, PSR10), cbit(TIMSK, TOIE1)

Das Macro |CODEBLOCK| mach den zu untersuchenden Code noch etwas 
übersichtlicher
1
#define CODEBLOCK(x)  do { x } while(0)

Vor der eigentlichen Nutzung muss die System-Ausführungszeit bestimmt 
werden. Das mache ich durch einen einfachen Aufruf von start / stop 
t1_counter und speichern der Ticks in einer globalen Variable 
|u32_self_tick|:
1
  // Messung der Ticks für die Funktionsaufrufe
2
  start_t1_counter();
3
  stop_t1_counter();
4
  uint32_t u32_self_tick = read_t1_counter();


Und so sieht dann ein Messbeispiel aus:
1
  start_t1_counter();
2
  CODEBLOCK( /* mein code */ );  // hier die Optimierung abschalten !!
3
  stop_t1_counter();
4
5
  uint32_t ticks = read_t1_counter() - u32_self_tick;

Ausgeben kann man das dann über ein LCD-Display oder auch über die 
serielle Schnittstelle.

Siehe: Beitrag "Re: Stack Überschreiber beim Rechnen mit uint64_t"

.

von Stefan R. (Gast)


Lesenswert?

@Johann L:

Ich hatte schon vermutet, dass dieser Satz

>> und am besten sogar noch nach C-Kommandos zusammengefasst,
>
> Das ist nicht möglich, da markttaugliche C-Compiler schon seit
> mindestens 20 Jahren nicht mehr nach dem Prinzip eines Makro-Assemblers
> functionieren.
> D.h. je nach Kontext sieht deine "i = i + 1" komplett anders aus.

ein wenig missverständlich sein könnte. Ich wollte darauf hinaus, dass 
ja in der .lss immer die einzelnen C-Codes aufgelistet sind und dann der 
daraus (wie auch immer) generierte Maschinencode. So wie hier:
1
    lcd_putc(255);
2
 2b0:  8f ef         ldi  r24, 0xFF  ; 255
3
 2b2:  52 df         rcall  .-348      ; 0x158 <lcd_putc>

Dass es nicht geht, einem Codefragmenbt in C eine Ausführzeit direkt 
zuzuordnen, habe ich mir schon fast gedacht.

@Uwe S.:

Da ich nur knapp über Null Ahnung von der Materie habe, muss ich Deinen 
Beitrag erst einmal genau sichten.

Aber vielen Dank erst einmal für die Antworten!
Stefan

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.