Forum: Mikrocontroller und Digitale Elektronik Arm CortexM4 nstruction Timing


von Martin O. (ossi-2)


Lesenswert?

Ich versuche derzeit das Instruction Timing der CPU auf dem Teens36 
Board zu verstehen. Dazu lasse ich kurze Codestücke N mal in einer 
Schleife ausführen und messe dann mit micros() die Zeit. Dann zeige ich 
die Zeit in Zyklen pro Durchlauf an.
Bei dem Programm unten habe ich folgenden Effekt. Ich lasse zeimal 
dieselbe Messung laufen. Einmal erhalte ich 7 Zyklen, das zweite mal 6 
Zyklen. Wenn ich vor dem ersten Stück Code einen NOP einbaue vertauschen 
sich die Werte.

Es scheint also mit dem Alignment des Codes zusammenzuhängen. Weiss 
jemand näheres? Wo finde ich Info darüber?

1
void setup() {
2
  Serial.begin(115200); 
3
  delay(1000); 
4
  Serial.print("Hello World 1\n"); 
5
  int N=100000 ;
6
  double fClock=180e6 ;
7
  int32_t start ;
8
  int32_t stop ;
9
  double T ;
10
  int sum ;
11
  int x ;
12
  float fsum ;
13
  float fx ;
14
  float fy ;
15
// erstes Stück
16
  // 7 cycles
17
  start=micros() ;
18
  fsum=0 ;
19
  fx=1 ;
20
  fy=2 ;
21
  for(int k=1 ; k<=N ; k++){
22
    fx += 2.0 ;
23
    fy += 3.0 ;
24
    fsum += fx*fy ;
25
    }
26
  stop=micros() ;
27
  Serial.printf("sum=%15.10e\n",fsum) ;
28
  T=(stop-start)*1e-6 ;
29
  Serial.printf("test10a  %8.2f cycles \n",T/N*fClock) ;
30
// zweites Stück
31
  // 6 cycles
32
  asm volatile ("NOP ; // LOOP-10a\n   ");
33
  start=micros() ;
34
  fsum=0 ;
35
  fx=1 ;
36
  fy=2 ;
37
  for(int k=1 ; k<=N ; k++){
38
    fx += 2.0 ;
39
    fy += 3.0 ;
40
    fsum += fx*fy ;
41
    }
42
  stop=micros() ;
43
  Serial.printf("sum=%15.10e\n",fsum) ;
44
  T=(stop-start)*1e-6 ;
45
  Serial.printf("test10b  %8.2f cycles \n",T/N*fClock) ;
46
  }
47
  
48
void loop(){
49
  }

von Jim M. (turboj)


Lesenswert?

Martin O. schrieb:
> Weiss
> jemand näheres? Wo finde ich Info darüber?

Technical Reference Manual bei Arm.com gelesen?

Der Instruction Fetcher arbeitet 32-bittig und muss bei mis-alignment 
also entweder 16 Bits wegschmeissen oder gar auf den nächsten Fetch 
warten um eine 32-Bit Instruktion zusammen bauen zu können.

Einer der zahlreichen Gründe wieso man bei diesen µCs besser den C 
Compiler bemüht.

Übrigens müsste der Optimizer die Schleifen eigentlich wegoptimieren 
können.

von Mitlesa (Gast)


Lesenswert?

Jim M. schrieb:
> Der Instruction Fetcher arbeitet 32-bittig und muss bei mis-alignment
> also entweder 16 Bits wegschmeissen oder gar auf den nächsten Fetch
> warten um eine 32-Bit Instruktion zusammen bauen zu können.

Und wer Mikrosekunden misst (zwangsläufig hier auf Mikrosekunden
quantisiert) bekommt Quantisierungsfehler in der Messung.

von ... (Gast)


Lesenswert?

Nimm mal richtiges C und nicht dieses Antuinogestammel.

Sowas macht Mann mit dem Systick.
Ohne viele Header etwa so:
1
//  start systick
2
*((volatile uint32_t*)0xE000E014) = 0xFFFFFF;
3
*((volatile uint32_t*)0xE000E010) = 0x3;
4
tstart = (*((volatile uint32_t*)0xE000E018));
5
6
code ...


Nebenwirkungen: Der Systickinterrupt wird nur noch alle paar
Sekunden aufgerufen.

von foobar (Gast)


Lesenswert?

Bei solchen CPUs Taktzyklen zählen ist nicht allzu sinnvoll, da das 
Timing nicht mehr wirklich determinstisch ist - das Teil hat nen Cache 
und Waitstates je nach Bus-Contention etc.

von Martin O. (ossi-2)


Lesenswert?

>Bei solchen CPUs Taktzyklen zählen ist nicht allzu sinnvoll

Mir ist schon klar, dass meine Zyklenzählen grenzwertig ist. Ich möchte 
aber eine Vorstellung gewinnen, wie sich die Laufzeit bestimmter 
Algorithmen (z.B. digitaler Filter) ergibt.

Der Optimierer ist schon sehr klever, aber diesen Code hat er nicht 
wegoptimiert.


>//  start systick
>*((volatile uint32_t*)0xE000E014) = 0xFFFFFF;
>*((volatile uint32_t*)0xE000E010) = 0x3;
>tstart = (*((volatile uint32_t*)0xE000E018));
>
>code ...
Wenn das die Alternative zu Arduino ist dann bleibe ich lieber beim 
Arduino....

: Bearbeitet durch User
Beitrag #5849494 wurde von einem Moderator gelöscht.
von Stefan F. (Gast)


Lesenswert?

... schrieb:
> Nimm mal richtiges C und nicht dieses Antuinogestammel.
> Sowas macht Mann mit dem Systick. Ohne viele Header etwa so:
>
> *((volatile uint32_t*)0xE000E014) = 0xFFFFFF;
> *((volatile uint32_t*)0xE000E010) = 0x3;
> tstart = (*((volatile uint32_t*)0xE000E018));

Ich habe gerade mal nach "Antuino" gegoogelt und dabei ausschließlich 
Trollerei von einem Gast gefunden.

Beitrag #5849513 wurde von einem Moderator gelöscht.
Beitrag #5849532 wurde von einem Moderator gelöscht.
von ... (Gast)


Lesenswert?

>>//  start systick
>>*((volatile uint32_t*)0xE000E014) = 0xFFFFFF;
>>*((volatile uint32_t*)0xE000E010) = 0x3;
>>tstart = (*((volatile uint32_t*)0xE000E018));
>>
>>code ...
>Wenn das die Alternative zu Arduino ist dann bleibe ich lieber beim
>Arduino...

Daran das du an diesem simplen 3-Zeiler nicht den Inhalt zu
verstehen in der Lage bist, sehe ich meine These bestaetigt:

Antuino macht in erster Linie dumm.

Und mancher scheint auch dumm bleiben zu wollen.

von (prx) A. K. (prx)


Lesenswert?

Dass politische Diskussionen zur Schlammschlacht werden, ist normal. 
Dass Diskussionen über "was ist besser, X oder Y" auch dazu neigen, 
kennt man. Aber dass man sogar beim Instruction Timing übereinander 
herfällt, bloss weil jemand Jehova gesagt hat?

: Bearbeitet durch User
von Bauform B. (bauformb)


Lesenswert?

... schrieb:
> Sowas macht Mann mit dem Systick.

Der cortex M4 kann es besser (auch wenn's hier total OT ist)
1
   DEBUG->TRCENA = 1;
2
   DWT->CYCCNT = 0;          // alternativ
3
   DWT->CYCCNT_EN = 1;
4
   timestamp0 = DWT->CYCCNT; // alternativ
5
// code...
6
   timestamp1 = DWT->CYCCNT;

von Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite


Lesenswert?

Martin O. schrieb:
> Ich versuche derzeit das Instruction Timing der CPU auf dem Teens36
> Board zu verstehen.
...

Dann schau Dir PM0214, das Listfile, RM0090 an. In ungefähr dieser 
Reihenfolge. Und dann einfach mal ein kleines Maschinenprogramm für den 
ARM schreiben.

Zum Aufwärmen könntest Du aber auch den kleinen M0 Core anschauen: 
PM0215, RM0091.

Falls das Dein erster Kontakt zu Maschinensprache ist, dann wäre 
AVR-Assembler (bekannt von den Arduinos) ein schöner Einstieg.

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.