- Akku Tests und Balkonkraftwerk Speicher         
Seite 2 von 2 ErsteErste 12
Ergebnis 11 bis 20 von 20

Thema: AVR/Bascom geschwindigkeit grundrechenarten

  1. #11
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Anzeige

    Powerstation Test
    Bei nur 85 Zyklen kann man kaum eine richtige Reihenentwicklung mehr machen. Das kommt mir auch ausgesprochen kurz vor. ZU erwarten wären eigentlich Zeiten etwas langsamer als eine Division.
    Kann es sein das das nur für einen Speziellen Wert (z.B. 0) gilt, oder für Integer als Ergebnis ?

  2. #12
    Erfahrener Benutzer Roboter Experte Avatar von ikarus_177
    Registriert seit
    31.12.2007
    Ort
    Grein
    Alter
    31
    Beiträge
    601
    Das ist schon sehr seltsam:

    bei
    Code:
    dim C as single
    C = sin(3.1415)
    braucht man die ca. 85 Zyklen.

    bei
    Code:
    dim C as single
    C = 3.1415
    
    C = sin(C)
    sinds schon über 2500 Zyklen...

    Hat jemand vielleicht eine Erklärung dafür?

    Alle Angaben wie immer ohne Gewähr

  3. #13
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Bei dem ersten Beispiel wird der Sinus während des Compilierens ausgerechenet. Wofür dann noch 85 Zyklen gebraucht werden weiss ich nicht. Das Kopieren einer Konstante solle nicht so lange dauern.

    Beim 2 ten Beispiel scheint der Compiler das nicht so weit zu optimieren wie im ersten Beispiel. Da wird dann der Sinus wohl wirklich ausgerechent. Die Zeit sieht auch irgendwie realistisch aus für eine Reihentwicklung. Noch etwas langsamer ist meistens log und der Arcus-Tangens.

  4. #14
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    *lol* Wenn man beide Varianten in EINE source schreibt, ersparte er sich die ganze Rechnerei und nimmt nur Literale.
    (müsste man gucken, ob das nur für PI gilt oder für alle werte
    Code:
    //----------------------------------------	
    C = Sin(3.1415)
    //----------------------------------------	
    	LDI	XL,0x60
    	LDI	XH,0x00
    	LDI	ZL,0x8C
    	LDI	ZH,0x03
    	CALL	L_0x0276	// 4 Byte Literal 0x38C --> C-single
    //----------------------------------------	
    C = 3.1415
    //----------------------------------------	
    	LDI	XL,0x60
    	LDI	XH,0x00
    	LDI	ZL,0x90
    	LDI	ZH,0x03
    	CALL	L_0x0276	// 4 Byte  Literal 0x390 --> C-single
    //----------------------------------------	
    C = Sin(c)
    //----------------------------------------	
    	LDI	ZL,0x60
    	LDI	ZH,0x00
    	CALL	L_0x036E	// C-single --> R13, 14, 15, 16
    	LDI	ZL,0x0D
    	LDI	ZH,0x00
    	LDI	XL,0x60
    	LDI	XH,0x00
    	CALL	L_0x0286	// R13, 14, 15, 16 --> C-single
    
    //----------------------------------------	
    	CLI                     // "END"
    L_0x00B8:
    	RJMP	L_0x00B8	
    
    Literal-0x038c	
         .DB	0x04, 0x4F, 0xC2, 0x38
    
    Literal-0x0390
         .DB	0x56, 0x0E, 0x49, 0x40	;.O.8V.I@
    jetzt schau ich mir noch an, was er macht, wenn ich ihn zum Rechnen zwinge
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  5. #15
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    mich würde mal ein arcus sinus interessieren, wie unterschiedlich verhalten sich eigentlich C und Bascom bei solchen sachen ... in C verwende ich die math.h von winavr

  6. #16
    Super-Moderator Robotik Visionär Avatar von PicNick
    Registriert seit
    23.11.2004
    Ort
    Wien
    Beiträge
    6.842
    Du, das ist Arbeit.
    Ich stell gerne den disassemblierten Basic für ASIN hier rein, und wenn mir einer irgendeinen Code als .HEX File gibt, kann ich den auch disassemblieren und herzeigen.
    Aber das durchhacken und kommentieren muss ich fleissigen Leuten überlassen
    Angehängte Dateien Angehängte Dateien
    mfg robert
    Wer glaubt zu wissen, muß wissen, er glaubt.

  7. #17
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    11.12.2007
    Ort
    weit weg von nahe Bonn
    Alter
    39
    Beiträge
    3.416
    achso, ich dachte du hast dir nen debugger o.ä. zur brust genommen und einfach gemessen ^^

    ich hab atm auch zu viel um die ohren um mir das auszurechnen oder nachzulesen, aber n kollege von mir müsste u.a. mit asin arbeiten und das könnte eventuell zeitkritisch werden, da wollt ich einfach mal nachfragen

  8. #18
    Benutzer Stammmitglied
    Registriert seit
    12.12.2004
    Ort
    Trier
    Beiträge
    38
    Sorry, wenn ich diesen "alten" Thread auspacke. Ich bin auf ihn gestossen, weil ich zur Laufzeitoptimierung meiner DS1820-Temperatur-Auswertung ein paar Anregungen gesucht habe.

    Zitat Zitat von mycroc
    ich hatte einige umstimigkeiten mit der geschwindigkeit in der die grundrechenarten in kombination mit verschiedenen Datentypen ausgefürt werden. Ich habe daswegen alles mal im Bascom Simulator getestet(ohne Gewähr)
    Code:
    $regfile = "m32def.dat"
    $crystal = 11059200
    
    Dim B1 As Byte
    Dim B2 As Byte
    Dim B3 As Byte
    Dim I1 As Integer
    Dim I2 As Integer
    Dim I3 As Integer
    Dim W1 As Word
    Dim W2 As Word
    Dim W3 As Word
    Dim L1 As Long
    Dim L2 As Long
    Dim L3 As Long
    Dim S1 As Single
    Dim S2 As Single
    Dim S3 As Single
    Dim D1 As Double
    Dim D2 As Double
    Dim D3 As Double
    
    B1 = 80
    I1 = 80
    W1 = 80
    L1 = 80
    S1 = 80
    D1 = 80
    B2 = 8
    I2 = 8
    W2 = 8
    L2 = 8
    S2 = 8
    D2 = 8
    
    
    Do
    B3 = B1 + B2                                                '9
    
    B3 = B1 - B2                                                '9
    
    B3 = B1 * B2                                                '10
    
    B3 = B1 / B2                                                '112
    
    Shift , B1 , Right , 3                                      '27
    
    I3 = I1 + I2                                                '20
    
    I3 = I1 - I2                                                '20
    
    I3 = I1 * I2                                                '39
    
    I3 = I1 / I2                                                '291
    
    Shift , I1 , Right , 3                                      '34
    
    W3 = W1 + W2                                                '20
    
    W3 = W1 - W2                                                '20
    
    W3 = W1 * W2                                                '39
    
    W3 = W1 / W2                                                '255                                                '
    
    Shift , W1 , Right , 3                                      '34
    
    L3 = L1 + L2                                                '41
    
    L3 = L1 - L2                                                '41
    
    L3 = L1 * L2                                                '87
    
    L3 = L1 / L2                                                '787
    
    Shift , L1 , Right , 3                                      '48
    
    S3 = S1 + S2                                                '162
    
    S3 = S1 - S2                                                '171
    
    S3 = S1 * S2                                                '420
    
    S3 = S1 / S2                                                '527
    
    Shift , S1 , Right , 3                                      '73
    
    D3 = D1 + D2                                                '315
    
    D3 = D1 - D2                                                '378
    
    D3 = D1 * D2                                                '455
    
    D3 = D1 / D2                                                '1760
    
    Shift , D1 , Right , 3                                      '1
    
    Loop
    
    
    End                                                         'end program
    Die Komentare in der jeweiligen zeile sind nach Simulator die benötigten zyklen die für die berechnung benötigt werden. Mir hat es geholfen und deswegen wolte ich die ganze mühe nicht für mich behalten.
    Ich möchte anmerken, das Schiebeoperationen als Ersatz für Divisionen durch 2, 4, 8, ... nur für vorzeichenlose, ganzzahlige Variablentypen (Byte, Word, Long) äquivalent sind, da Bascom bei Schiebeoperationen nicht das Vorzeichen berücksichtigt. D.h. Rechtsschieben bei Integervariablen ist nur solange korrekt, wie die Integervariable größer/gleich Null ist.
    In folgendem Programmbeispiel habe ich eine Integer-Division durch 2 mit Hilfe des Inline-Assemblers realisiert und mit der Integer-Division selbst, sowie dem einfachen Rechtsschieben verglichen.

    Das Programmbeispiel kann direkt im Simulator ausgeführt werden.

    Code:
    Dim X0 As Byte , X1 As Byte
    Dim X As Integer At X0 Overlay
    Dim Y As Integer
    
    Do
    '*******************************************************************************
    '***   Integer Variable eingeben                                             ***
    '*******************************************************************************
    
    Input "x:" , X
    nop
    
    '*******************************************************************************
    '***   Integer-Division durch 2                                              ***
    '*******************************************************************************
    
    Y = X / 2
    nop
    Print Y
    
    '*******************************************************************************
    '***   Rechtsschieben Integer Variable                                       ***
    '*******************************************************************************
    
    Y = X
    Shift Y , Right , 1
    Print Y
    nop
    
    '*******************************************************************************
    '***   Rechtsschieben Integer Variable mit Vorzeichen                        ***
    '*******************************************************************************
    
    push r24                                                    'R24 retten
    push r25                                                    'R25 retten
    
    lds r24,{x0}                                                'LSB Integer in R24
    lds r25,{x1}                                                'MSB Integer in R25
    
    sbrc r25,7                                                  'Wenn Integer negativ..
    adiw r24,1                                                  '..dann Incrementiere Integer
    asr r25                                                     'Rechtsschieben MSB
    ror r24                                                     'Rechtsschieben LSB
    
    sts {x0},r24                                                'R24 in LSB Integer
    sts {x1},r25                                                'R25 in MSB Integer
    
    pop r25                                                     'R25 wiederherstellen
    pop r24                                                     'R24 wiederherstellen
    nop
    Print X
    
    '*******************************************************************************
    
    Loop
    End
    MfG
    screwdriver


    edit:
    Der Variablentyp LONG hat einen Wertebereich von -2147483648 bis 2147483647 und ist zwar ganzzahlig aber vorzeichenbehaftet. Für Long gilt also das gleiche wie für Integer.

    Der im Codefenster vorgestellte Algorithmus ist direkt aus einem meiner Quelltexte kopiert. In etwas abgeänderter Form und als nettes Macro verpackt, ist er jedoch recht gut allgemein anwendbar. Wer möchte kann ja noch eine Zählschleife drumrum tun und kann somit Mehrfach-Shiften.

    Code:
    Dim Intvar As Integer                                       'Integervariable
    Dim Y As Integer
    
    '*******************************************************************************
    '***   Macro: Asr_Int16                                                      ***
    '*******************************************************************************
    '***   Aufruf mit Adresse der zu schiebenden Integervariable im Z-Register   ***
    '*******************************************************************************
    
    Macro Asr_int16
       ldd r24,z+0                                              'Lowbyte Integer in R24
       ldd r25,z+1                                              'Highbyte Integer in R25
    
       sbrc r25,7                                               'Wenn Integer negativ, ..
       adiw r24,1                                               '.. dann Intvar inkrementieren
       asr r25                                                  'Schiebe Highbyte rechts
       ror r24                                                  'Schiebe Lowbyte rechts
    
       std z+0,r24                                              'R24 in Lowbyte Integer
       std z+1,r25                                              'R25 in Highbyte Integer
    End Macro
    
    '*******************************************************************************
    '***   Hauptprogramm                                                         ***
    '*******************************************************************************
    Do
       Input "IntVar: " , Intvar
        
       Y = Intvar / 2
       
       Print Y
       
       Loadadr Intvar , Z              'Adresse Integervariable in Z-Register laden
       Asr_int16                       'Integervariable Rechtsschieben
       
       Print Intvar
    
    Loop
    
    End
    Laufzeiten:
    +1000 / 2 : 277 Zyklen, mit Asr_int16 nur 14 Zyklen
    -1000 / 2 : 312 Zyklen, mit Asr_int16 nur 15 Zyklen

  9. #19
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    14.01.2008
    Beiträge
    164
    ...Hat jemand vielleicht eine Erklärung dafür?....

    Also ich zweifle eure Zeitmessungen sehr stark an, weil ihr euch mit dem ASM-Code von Bascom überhaupt noch nicht geschäftigt habt.

    Werte mal die Zyklen vom ASM-Sourse aus, dann werdet ihr staunen, was da für Werte rauskommen. Und diese Werte sind auch die Zeiten, die der Atmega braucht.

  10. #20
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Die Zahlen sind schon plasibel. Wenn man das im Simulator durchläuft, nimmt einem der Simulator das zählen der Zyklen schon ab. Da muß man sich den Code auch gar nicht mehr anschauen. Nur wenn man wissen will wieso etwas besonders schnell oder langsam ist ist das nötig. Besonders bei Division und Multiplication kann die Zeit etwas von den Zahlen abhängen.

    Die echte Division ist halt recht langsam, daher die rund 300 Zyklen auch für eine Division durch 2. Der extra inline ASM code ist dann entsprechend schneller. Ein guter Compiler hätte das .../2 auch gleich durch den ASM code oben, oder zumindest was ähnliches ersetzt.

Seite 2 von 2 ErsteErste 12

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen