Forum: Mikrocontroller und Digitale Elektronik ASM code laufzeitoptimieren


von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Lesenswert?

Hi,
ich steh gerade aufm schlauch,
kann mir einer helfen diesen code auf max 10 clock cycles zu 
reduzieren??
im moment hat er 15,..
1
#define J 0x04
2
#define K 0x08
3
4
if_SE0:
5
in temp,USB_input
6
tst temp
7
breq ende
8
9
take_bits:
10
cpse temp,J
11
ori temp1,0x80
12
lsr temp1
13
14
byte_full:
15
dec bit_counter
16
brne count_loops
17
st y+,temp1
18
ldi bit_counter,0x08
19
20
count_loops:
21
dec loop_counter
22
brbs 1,ende
23
24
ijmp
25
26
ende:

Falls ihr fragen habt was ich da eigentlich mache, fragt ruhig,..

danke schon mal im vorraus

von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Lesenswert?

Schade das bis jetzt sich niemand gemeldet hat,..
zwar habe ich zwischendurch ein bissl zu tun gehabt aber um 1 cycle 
konnte ich das ganze schon mal reduzieren:
(beachte die schleife geht von if_SE0 bis ijmp)
1
#define J 0x04
2
#define K 0x08
3
#define Jr r17
4
ldi Jr,J
5
6
//###############
7
if_SE0:
8
in temp,USB_input
9
tst temp
10
breq ende
11
12
take_bits:
13
cpse temp,Jr
14
ori temp1,0x80
15
lsr temp1
16
17
byte_full:
18
brcc count_loops
19
st y+,temp1
20
andi temp1,0x40
21
22
count_loops:
23
dec loop_counter
24
brbs 1,ende
25
26
ijmp //to if_SE0:
27
28
ende:

von Hagen R. (hagen)


Lesenswert?

Um 1 Bit zu errechnen benötigst du mehrer Takte da du eine Schleife 
benutzt. Da die Anzahl der Bits immer 8 ist hilft hier Loop-Unrolling. 
Entferne deine Schleife und baue dafür für jedes einzelne Bit eine 
eigene Abfrage ein.

Damit eliminierst du

lsr tmp

und statt dessen für jedes deiner Datenbits eben ori temp, 0x01, ori 
temp,0x02 usw.

Auf bit_counter wird komplett verzichtet, ebenso dessen Loop usw.

Gruß Hagen

von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Lesenswert?

jo, stimmt,..cool
dann komme ich auf traumhafte 5,6 cycles pro bit,.. :)
das problem ist, (ich hatte es vorher leider net erwähnt)

vor if_SE0 stehen eigentlich ein paar nop worauf ijmp zeigt um eine 
variable laufzeit zwischen 10 und 14 cycles pro bit zu kommen, die 
vorher irgendwo berechnet werden; (also das minimum kann ruhig kleiner 
sein wenn dennoch die übergeben cyclezeit eingehalten werden kann)


irgend eine idee???
grüüüße und
daaaanke :)

von Hagen R. (hagen)


Lesenswert?

Jo, poste deine Frage im vollem Umfang damit wir auch korrekte Antworten 
liefern können. Denn deine Codefetzen können nur erhahnen lassen was du 
da real machst.

Mein Vorschlag kann auch mit deinem IJMP und der Taktausgleichung 
zusammenarbeiten. Du zählst ja sowieso erstmal nur 8 Bits runter bevor 
der IJMP ausgeführt wird. Davon abgesehen wird eine Loop die du 
aufdrösselst in ihrem Timing immer exakt sein. Statt alls per IJMP einen 
Ausgleich zu machen musst du nur sicherstellen das die Berechnung eines 
Bits immer die gleiche Taktanzahl aufweist. Das ist mit den Branchses im 
AVR sogar ideal gelösst.

Gruß Hagen

von Kai S. (Firma: ZeuSWarE GmbH) (zeusosc)


Lesenswert?

Hi hagen, danke für deine gedult

>Du zählst ja sowieso erstmal nur 8 Bits runter bevor
>der IJMP ausgeführt wird.

Es war so gedacht das das auslesen der bits mit ijmp delay'ed werden,
also ein bit in einen zeitraum zwischen  10 bis 14 cycles, die genaue 
anzahl wird vorher durch ein register übergeben und das ijmp (über 
zh:zl) so angepasst das es auf ein bis vier nop's vor dem 
schleifenbeginn springt.
>>Also einmal ijmp'en pro bit,..

ich habe übrigens noch einen fehler entdeckt der vorher vilt. falsche 
schlüsse ziehen ließ:
>edit:--------------------
1
#define J 0x04
2
#define K 0x08
3
#define Jr r17
4
ldi Jr,J
5
6
//###############
7
if_SE0:
8
in temp,USB_input
9
tst temp
10
breq ende
11
12
take_bits:
13
cpse temp,Jr
14
ori temp1,0x80
15
lsr temp1
16
17
byte_full:
18
brcc ende_schleife
19
st y+,temp1
20
andi temp1,0x40
21
22
count_loops:
23
dec byte_counter
24
brbs 1,ende
25
26
ende_schleife: ijmp //
27
28
ende:

verrechnet dadurch habe ich mich auch
währ ein schleifendurchschnitt:
(7* (if_SE0->brcc =true ==10(+delay))+(if_SE0->brcc=false ==7 + 7))/8 =
(70+(7*delay)+7+7+delay)/8=(84+8*delay)=10,5+delay
was auch schon eine ziemlich gute zeit aber nicht exakt ist,...

grüüüße :)

von Hagen R. (hagen)


Lesenswert?

Ich denke es wäre besser wenn du deinen ASM Code mal als Pseudocode 
postest. Ob das in Worten oder ind C/PASCAL erfolgt ist ziemlich egal 
das verstehen die Leute hier schon. Wichtig ist nur das das Problem 
klarer ersichtlich wird und das wir sehen wie du es lösen möchtest.

Leider ist das so nicht möglich, keiner hier hat die Lust deine Formeln 
zur Berechnung der Taktanzahlen nachzurechnen.

Hast du dir schon mal andere Software USB Sourcen angeschaut ? Es gibt 
im WEB mindestens 2 solcher lösungen für den AVR, auch die mussten ihr 
Bit/Bang Timing exakt einhalten. Dort wirst du fündig.

Gruß Hagen

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
Noch kein Account? Hier anmelden.