Hallo Community... Ich wollte gerade eine simple Gegenüberstellung von einigen AVRs und deren Berechnungszeit für eine "einfache" Rechnung aufstellen. Dafür habe ich einmal ergebnis = sqrt(465.983154/4135.964*sqrt(168*1256.942)); und einmal ergebnis = 1.0+1.0 gerechnet. Das ganze vorerst im Simulator. Was mich allerdings wundert: Egal was ich rechnen lasse, der Cyclecounter zeit immer 1 an und die StopWatch 60ns. Kennt zufällig jemand das Problem und kann mir weiterhelfen? Danke schonmal im Voraus. -- ATmega32@16Mhz AVR-Studio 5.1
Einfaches Hilfsmittel: Pin setzen Funktion / Berechnung aufrufen Pin rücksetzen so kann man einfach die Abarbeitungszeit einer Funktion betrachen.
Das wäre doch nichts anderes als die Berechnung per Knopfdruck zu starten. Ich will aber die genau Zeit wissen.
Da ich aufgrund deiner Beschreibung nichts sagen kann, bleibt nur der Hinweise auf das optionale (Dis-)Assembler-Listing . Mal eine Gegenfrage. Sind denn die AVR so unterschiedlich. Es kann doch nur einen Unterschied geben, wenn ein AVR-Typ beispielsweise einen Hardware-Multiplizierer besitzt und ein anderer nicht: ATTiny vs ATmega. (Die ganz alten lasse jetzt mal weg)
>ergebnis = sqrt(465.983154/4135.964*sqrt(168*1256.942)); > >und einmal > >ergebnis = 1.0+1.0 >Das ganze vorerst im Simulator. Was mich allerdings wundert: Egal was >ich rechnen lasse, der Cyclecounter zeit immer 1 an und die StopWatch >60ns. Was machst du mit ergebnis? Nichts, dann optimiert der Compiler dir den ganzen Kram weg. Versuch mal volatile float ergebnis.
Hallo Rush, schau dir mal den Assemblercode an, den der Compiler erzeugt. Im besten Fall macht der Atmega nämlich nur ne Zuweisung, und der Compiler rechnet das vorher schon aus. aus wird
1 | ergebnis = 1.0+1.0 |
wird dann
1 | ergebnis = 2.0 |
und aus
1 | ergebnis = sqrt(465.983154/4135.964*sqrt(168*1256.942)); |
wird
1 | ergebnis = 154.2442536 |
Was in der Ausführungszeit genau das gleiche ist! Ich bin mir jetzt nur nicht sicher, ob der Compiler so intelligent ist und kann die Funktion sqrt () rechnen. Aber das siehst du im Assemblercode. Und wenn du ergebnis nicht weiter benutzt, dann kann es dir passieren, dass der Compiler eh alles wegoptimiert. VG Thomas
Ich brauche diese Gegenüberstellung für die Vorlesung -.- Ich weiss, eigentlich totaler Quatsch aber was solls... Wollte das ganze auf diesen Typen laufen lassen: AT90S2313 ATtiny2313 ATmega8 - mega128 ATmega644 und 644P MSP430 Ich weiss nicht ob sich beispielsweise ein ATmega16 von dem Berechnungsalgorithmus von einem mega128 unterscheidet. Schätzungsweise nicht, aber muss es eben machen.
Zu den verschiedenen Controllern gibt von TI ein PDF (inkl. Quellcode) im Anhang zu diesem App-Note. Hilft Dir zwar jetzt nicht...
Das hier ist praktisch der Teil für die berechnung und ausgabe:
1 | sei(); |
2 | a = sqrt(465.983154/4135.964*sqrt(168*1256.942)); |
3 | cli(); |
4 | |
5 | dtostrf(a, 5,8, chr_a); |
6 | set_cursor(0,1); |
7 | lcd_string(chr_a); |
8 | itoa(i, chr_i, 10); |
9 | set_cursor(0,2); |
10 | lcd_string(chr_i); |
11 | |
12 | // chr_a = ergebnis string
|
13 | // i = Anzahl der Timerinterrupts
|
14 | // chr_i = Anzahl der Timerinterrupts als String
|
Assembler habe ich bis heute erfolgreich meiden können, von daher verstehe ich ihn nicht ;-) Thomas kannst du vielleicht drüber schauen? Habe den Assemblercode mal drangehängt.
Hi Wenn in deinem Code vor sei(); ein timerinit(); steht, dann fehlt der Assemblercode für a = sqrt(465.983154/4135.964*sqrt(168*1256.942)); MfG Spess
der dazugehörige c-code sieht so aus:
1 | /*
|
2 | * ATmega32_Berechnungsdauer.c
|
3 | *
|
4 | * Created: 22.03.2012 16:59:56
|
5 | * Author: Rush
|
6 | */
|
7 | |
8 | #include <avr/io.h> |
9 | #include <avr/interrupt.h> |
10 | #include "lcd-routines.h" |
11 | #include <math.h> |
12 | |
13 | extern void lcd_data(unsigned char temp1); |
14 | extern void lcd_command(unsigned char temp1); |
15 | extern void lcd_enable(void); |
16 | extern void lcd_init(void); |
17 | extern void lcd_home(void); |
18 | extern void lcd_clear(void); |
19 | extern void set_cursor(uint8_t x, uint8_t y); |
20 | extern void lcd_string(char *data); |
21 | |
22 | |
23 | volatile unsigned int i = 0; |
24 | volatile unsigned char chr_i[10]; |
25 | |
26 | volatile double d = 123.43684; |
27 | volatile unsigned char chr_d[10]; |
28 | |
29 | |
30 | |
31 | ISR(TIMER0_COMP_vect) |
32 | {
|
33 | |
34 | i++; |
35 | |
36 | }
|
37 | |
38 | void timerinit(void) |
39 | {
|
40 | //TCCR0 = (1<<WGM01) | (1<<CS00); //prescaler none; CTC-Mode
|
41 | //TCCR0 = (1<<WGM01) | (1<<CS01); //prescaler 8; CTC-Mode
|
42 | //TCCR0 = (1<<WGM01) | (1<<CS01) | (1<<CS00); //prescaler 64; CTC-Mode
|
43 | //TCCR0 = (1<<WGM01) | (1<<CS02); //prescaler 256; CTC-Mode
|
44 | TCCR0 = (1<<WGM01) | (1<<CS02) | (1<<CS00); //prescaler 1024; CTC-Mode |
45 | |
46 | OCR0 = 15; // ((1000000/8)/1000) = 125 für 1ms |
47 | TIMSK = (1<<OCIE0); // enable interrupts on compare match |
48 | |
49 | //Berechnung
|
50 | // 0,001sec / ((1/16000000)*Prescaler)
|
51 | }
|
52 | |
53 | int main(void) |
54 | {
|
55 | timerinit(); |
56 | |
57 | double a = 0; |
58 | char chr_a[100]; |
59 | |
60 | sei(); |
61 | a = sqrt(465.983154/4135.964*sqrt(168*1256.942)); |
62 | cli(); |
63 | dtostrf(a, 5,8, chr_a); |
64 | set_cursor(0,1); |
65 | lcd_string(chr_a); |
66 | itoa(i, chr_i, 10); |
67 | set_cursor(0,2); |
68 | lcd_string(chr_i); |
69 | |
70 | |
71 | while(1) |
72 | {
|
73 | |
74 | }
|
75 | }
|
dann frage ich mich ehrlich gesagt wo meine Berechnung hin ist. denn im Assenblercode folgt nach dem sei() direkt das cli(). Und was hat denn mein timerinit() mit dem Berechnungsteil zu tun? Eigentlich doch nichts.
Rush ... schrieb: > dann frage ich mich ehrlich gesagt wo meine Berechnung hin ist. wegoptimiert, der compiler hat es einfach ausgerechnet.
Hast recht. Habe jetzt die Optimierung ausgeschaltet. Jetzt kommt raus: ergebnis = 1.0 + 1.0 Cyclen: 13 StopWatch: 0,81 us bei ergebnis = sqrt(465.983154/4135.964*sqrt(168*1256.942)) kommen wieder die selben werte drin. und diesmal steht die berechnung im assemblercode auch drin. Kann doch wirklich nicht sein dass beide Berechnungen die selben Zeiten bringen...
Rush ... schrieb: > Hast recht. Habe jetzt die Optimierung ausgeschaltet. Jetzt kommt raus: jetzt hast du aber auch keine sinnvollen ergebnisse mehr. Denn kein sinnvolles Programm wird ohne optimierung eingesetzt. du must also den compiler dazu bringen, mit optimierung zu rechnen.
na das ergebnis stimmt schonmal. du hast ja recht was die optimierung angeht. mir gehts einfach nur darum dass ich mit ein und denselben einstellungen das selbe programm auf mehreren controllern laufen lasse. einfach nur um die vergleichbarkeit zu schaffen. sicher, normalerweise gehört dort die optimierung mit rein. naja, mit wenn ich meine ergebnisvariable als volatile deklariere dann wird sie auch nicht wegoptimiert.
Rush ... schrieb: > naja, mit wenn ich meine ergebnisvariable als volatile deklariere dann > wird sie auch nicht wegoptimiert. die variabel nicht, aber die berechnung kann dann genso weg optimiert werden. Es bleibt nur noch das ergebniss stehen.
sorry, hab mich falsch ausgedrückt. also die berechnung steht komplett im assemblercode drin
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.