mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ASM code laufzeitoptimieren


Autor: Kai Scheddin (zeusosc)
Datum:

Bewertung
0 lesenswert
nicht 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,..
#define J 0x04
#define K 0x08

if_SE0:
in temp,USB_input
tst temp
breq ende

take_bits:
cpse temp,J
ori temp1,0x80
lsr temp1

byte_full:
dec bit_counter
brne count_loops
st y+,temp1
ldi bit_counter,0x08

count_loops:
dec loop_counter
brbs 1,ende

ijmp

ende:

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

danke schon mal im vorraus

Autor: Kai Scheddin (zeusosc)
Datum:

Bewertung
0 lesenswert
nicht 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)

#define J 0x04
#define K 0x08
#define Jr r17
ldi Jr,J

//###############
if_SE0:
in temp,USB_input
tst temp
breq ende

take_bits:
cpse temp,Jr
ori temp1,0x80
lsr temp1

byte_full:
brcc count_loops
st y+,temp1
andi temp1,0x40

count_loops:
dec loop_counter
brbs 1,ende

ijmp //to if_SE0:

ende:

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kai Scheddin (zeusosc)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Kai Scheddin (zeusosc)
Datum:

Bewertung
0 lesenswert
nicht 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:--------------------
#define J 0x04
#define K 0x08
#define Jr r17
ldi Jr,J

//###############
if_SE0:
in temp,USB_input
tst temp
breq ende

take_bits:
cpse temp,Jr
ori temp1,0x80
lsr temp1

byte_full:
brcc ende_schleife
st y+,temp1
andi temp1,0x40

count_loops:
dec byte_counter
brbs 1,ende

ende_schleife: ijmp //

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 :)

Autor: Hagen Re (hagen)
Datum:

Bewertung
0 lesenswert
nicht 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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.