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 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
Lesezeichen