mikrocontroller.net

Forum: Compiler & IDEs Optimierung SPI Ausgabe


Autor: Christian U. (z0m3ie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist es möglich diesen Code noch zu optimieren ?
Die SPI Ausgabe ist einfach zu langsam ich komme aber nicht weiter, 
letterptr ist der Anfang in einer lookup Tabelle, a stellt dann den 
index innerhalb der Tabelle dar. Das ganze aus dem Ram statt Flash zu 
machen scheint keinen Geschwindigkeitsvorteil zu bringen.
Ich bin nun absoulut kein Assembler Freak wäre es möglich da mit 
Assembler noch ein paar Takte rauszuholen ?

a = *textptr++;
nextbyte = pgm_read_byte(letterptr+a);
while (*textptr != 0)
  {
    a = *textptr++;
    SPDR = nextbyte;
    nextbyte = pgm_read_byte(letterptr+a);
    while(!(SPSR & (1<<SPIF)));
  }
SPDR = nextbyte;
while(!(SPSR & (1<<SPIF)));

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian Ulrich (z0m3ie)

>Ist es möglich diesen Code noch zu optimieren ?

Sicher.

>Die SPI Ausgabe ist einfach zu langsam ich komme aber nicht weiter,
>letterptr ist der Anfang in einer lookup Tabelle, a stellt dann den
>index innerhalb der Tabelle dar. Das ganze aus dem Ram statt Flash zu
>machen scheint keinen Geschwindigkeitsvorteil zu bringen.

Tut es auch nicht. Siehe hier.

AVR-Tutorial: Schieberegister

>Ich bin nun absoulut kein Assembler Freak wäre es möglich da mit
>Assembler noch ein paar Takte rauszuholen ?

Nicht wirklich. C wird schon brauchbar übersetzt, wenn man es richtig 
hinschreibt.

Etwa so.

a = *textptr++;
nextbyte = pgm_read_byte(letterptr+a);
while (a != 0)
  {
    while(!(SPSR & (1<<SPIF)));
    SPDR = nextbyte;
    a = *textptr++;
    nextbyte = pgm_read_byte(letterptr+a);
  }
while(!(SPSR & (1<<SPIF)));
SPDR = nextbyte;
while(!(SPSR & (1<<SPIF)));

Der Trick dabei ist, während die Übertragung läuft das nächste Byte zu 
holen und danach erst zu prüfen, ob sie zu Ende ist. In deinem Beispiel 
verplemperst du Zeit um auf das Ende der Übertragung zu warten und 
DANACH erst das nächste Byte zu holen.

MFG
Falk

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich bin nun absoulut kein Assembler Freak wäre es möglich da mit
> Assembler noch ein paar Takte rauszuholen ?

Dazu müßte man sich den ASM-Code, den der Compiler erzeugt, mal näher 
ansehen und überlegen, was man besser machen kann. Dem C-Code sieht man 
das nicht an.

Autor: Christian U. (z0m3ie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk,

in der Zwischenzeit hatte ich das selbst schon gesehn und meinen Code so 
geändert:

a = *textptr++;
nextbyte = pgm_read_byte(letterptr+a);
while (*textptr != 0)
  {
    SPDR = nextbyte;
    a = *textptr++;
    nextbyte = pgm_read_byte(letterptr+a);
    while(!(SPSR & (1<<SPIF)));
  }
SPDR = nextbyte;
while(!(SPSR & (1<<SPIF)));

Damit sollte das ja wenn ich das richtig seh keinen unterschied mehr zu 
deinem code machen. Jedoch hat das nicht genug gebracht. ich hab immer 
noch lücken in der ausgabe die so groß sind wie die ausgabezeit selbst.

Ich hab auch schon mit dem Assemblercode geschaut und das vorher schon 
etwas optimiert nur programmiere ich nie in assembler und kann so 
schlecht einschätzen ob man das nicht inline optimaler lösen könnte.
ich poste montag mal den erzeugten code.

Autor: Alexander H. (ill_son)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

probiers doch mal mit Interrupt. Dann musst das Programm nicht warten, 
bis die Übertragung fertig ist, sondern bekommst das per Interrupt 
mitgeteilt.

Gruß, Alex

Autor: Christian U. (z0m3ie)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich fürchte das wird eher schlimmer da ich ja irgendwann die neuen daten 
holen muss. Das mach ich jetzt wärend der Ausgabe, dann kann ich das 
aber nicht mehr machen.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Alexander Heß (ill_son)

>probiers doch mal mit Interrupt. Dann musst das Programm nicht warten,
>bis die Übertragung fertig ist, sondern bekommst das per Interrupt
>mitgeteilt.

Und? Wird es dann schneller? NEIN! Für maximale SPI Geschwindigkeit muss 
man pollen.


@ Christian Ulrich (z0m3ie)

>in der Zwischenzeit hatte ich das selbst schon gesehn und meinen Code so
>geändert:

Warum fragst du zweimal *textptr ab? Da muss der Compiler, wenn er es 
nicht erkennt, zweimal den Pointer defererenzieren, obwohl a den 
gleichen Inhalt hat.

>a = *textptr++;
>nextbyte = pgm_read_byte(letterptr+a);
>while (*textptr != 0)
>  {
>    SPDR = nextbyte;
>    a = *textptr++;
>    nextbyte = pgm_read_byte(letterptr+a);
>    while(!(SPSR & (1<<SPIF)));
>  }
>SPDR = nextbyte;
>while(!(SPSR & (1<<SPIF)));

Pssst soweit. Besser kann man es wahrscheinlich nicht machen. Und man 
muss sehen, dass da immerhin zwei Pointer dereferenziert werden müssen.

>    a = *textptr++;

Das ist recht einfach, daraus wird eine ld rx,z+

>    nextbyte = pgm_read_byte(letterptr+a);

Hier muss jedes mal letterptr geladen werden und der Offset a als 16 Bit 
Offset addiert werden, dann kommt lpm. Das dauert schon ein paar Takte.

>deinem code machen. Jedoch hat das nicht genug gebracht. ich hab immer
>noch lücken in der ausgabe die so groß sind wie die ausgabezeit selbst.

Naja, rechne mal. Bei SPI-Takt = CLK/2 bleiben gerade mal 16 Takte pro 
Byte. Das wird knapp mit den zwei Pointeroperationen.

>ich poste montag mal den erzeugten code.

OK.

MfG
Falk

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.