Sinusberechnung LPC vs AVR

Gast #629020
Lesenswert?

Ich habe bis jetzt nur mit AVR gearbeitet.
Da ich für ein kommendes Projekt viel rechnen muss habe ich mir mal das 
Keil ARM Eval Kit runtergeladen.
Dann habe ich einfach mal in das Blinky Beispiel folgende Berechnung 
eingefügt:
Static float x = 3.14;
X = sin(x);

Im Keil Simulator benötigt der LPC im ARM Modus ca. 25.000 Zyklen und 
ca. 400µs für die Berechnung bei 60MHz Takt.
Mein AVR mit 20 MHz Takt mit WINAVR benötigt für dieselbe Berechnung die 
gleiche Zeit.
Ist das normal das der LPC (bzw. die Keil sinus lib) so langsam ist?

Gruß
Bernd
Gast #629042
Lesenswert?

Ich weiß nicht was die Keil Lib da macht aber die sin()
Funktion rechnet eigentlich mit doppelter Genauigkeit.
Da hilft es auch nicht einen float zu übergeben.
Das das 25000 Takte dauern soll überrascht mich aber schon
etwas.
Der avr-gcc verwendet bei Gleitkomma immer 'float'.

Mit dem Codevision AVR dauert die Rechnung übrigens 130µs. Der
rechnet wie der GCC mit 32bit.


 - Michael
Gast #629169
Lesenswert?

Ich habe das jetzt mal gemessen:
1
volatile unsigned int value1, value3;
2
volatile float x = 3.14;
3

4
//! test
5
value1 = T0TC;
6
x = sin(x);
7
value3 = T0TC;
8
value3 -= value1;
9
rprintf("Ergebnis: %u\n", value3);
10
// /test
11

12
.lss:
13
    //! test
14
    value1 = T0TC;
15
     598:  e2865901   add  r5, r6, #16384  ; 0x4000
16
     59c:  e5953008   ldr  r3, [r5, #8]
17
     5a0:  e59f60ec   ldr  r6, [pc, #236]  ; 694 <.text+0x694>
18
     5a4:  e5863000   str  r3, [r6]
19
    x = sin(x);
20
     5a8:  e59f40e8   ldr  r4, [pc, #232]  ; 698 <.text+0x698>
21
     5ac:  e5940000   ldr  r0, [r4]
22
     5b0:  eb000fff   bl  45b4 <__aeabi_f2d>
23
     5b4:  eb000748   bl  22dc <sin>
24
     5b8:  eb0011aa   bl  4c68 <__aeabi_d2f>
25
     5bc:  e5840000   str  r0, [r4]
26
    value3 = T0TC;
27
     5c0:  e5953008   ldr  r3, [r5, #8]
28
     5c4:  e59f10d0   ldr  r1, [pc, #208]  ; 69c <.text+0x69c>
29
     5c8:  e5813000   str  r3, [r1]
30
    value3 -= value1;
31
     5cc:  e5913000   ldr  r3, [r1]
32
     5d0:  e5962000   ldr  r2, [r6]
33
     5d4:  e0623003   rsb  r3, r2, r3
34
     5d8:  e5813000   str  r3, [r1]
35
    rprintf("Ergebnis: %u\n", value3);
36
     5dc:  e5911000   ldr  r1, [r1]
37
     5e0:  e59f00b8   ldr  r0, [pc, #184]  ; 6a0 <.text+0x6a0>
38
     5e4:  eb000042   bl  6f4 <rprintf>
39
    // /test

Der Timer0 zählt mit einer Auflösung von 1µs und die Ausgabe
ist: "Ergebnis: 48"
Gerechnet wird mit double. Das ganze läuft auf einem LPC2148
bei 60MHz.
Compiler: arm-elf-gcc (GCC) 4.1.2 (WinARM 4/2007)

 - Michael
Gast #629250
Lesenswert?

Hi,
Danke für deine Mühe.
Ich habe jetzt auch mal den Timer mitlaufen lassen - mit dem gleichen 
Ergebnis.
Mit der Keil GNU IDE bekomme ich nach der sin Berechnung einen Timerwert 
von 459 = 459 µS. Also ca. den Faktor 10 langsamer als bei dir.
Ich habe mal meinen Code mit Startup usw. beigefügt.
Vielleicht kannst du ihn mal bei dir testen?
Angehängte Dateien:
Gast #629441
Lesenswert?

Seltsam. Ich prüfe noch mal meine Timer-Konfiguration.
Der Teiler steht auf 60-1 aber vielleicht ist die PClk
langsamer als 60MHz. Am besten lasse ich mal eine LED
im Sekundentakt timergesteuert blinken.
Mal sehe ob ich heute Abend dazu komme weiter zu forschen
bzw. deinen Code laufen zu lassen.

 - Michael
Gast #632010
Lesenswert?

Sorry, hat etwas gedauert. Ich habe mir mein Programm bzw.
die Konfiguration nochmal angesehen und ich bin mir sicher
das F_CLK = P_CLK = 60MHZ ist.
Toggeln einer LED und rücksetzen von Timer0 wenn T0TC
1.000.000 erreicht hat führt zu einer Blinkfrequenz von
0,5Hz (1s an, 1s aus).

Dein Testprogramm habe ich nicht laufen lassen aber die
startup.s habe ich mir angesehen. Meiner Ansicht nach stimmt
die PLL Initialisierung nicht.
1
.equ    PLLCFG_MSEL,    (0x1F<<0)   /* PLL Multiplier */
2
.equ    PLLCFG_PSEL,    (0x03<<5)   /* PLL Divider */
Das sind die Konstanten M und P. P steht hier auf 8, was
völlig O.k ist aber M ist 32. Laut dem PLL-Tool von
Philips entspricht das (theoretisch) einer F_CLK von 384MHz.
Bei einem 12MHz Quarz müßte M=8 sein.

Was passiert denn wenn du die MSEL Zeile wie folgt abänderst:
1
.equ    PLLCFG_MSEL,    (0x04<<0)   /* PLL Multiplier */
Vielleicht interessiert sich der Simulator aber auch gar nicht
dafür (ich habe den nie benutzt).

Wenn ich das richtig überblicke wird in der timer.c der Timer
durch den Match-Interrupt alle 155µs zurückgesetzt und 'timeval'
um eins hochgezählt. Zumindest dann wenn der Kern mit 60MHz
getaktet wird. Die Peripherie läuft dann mit 30MHz.

 - Michael

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren