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