www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik code effizienter gestalten


Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Abend!
Ich stehe zur Zeit vor folgendem Problem.Hier erstmal der Code
SEGPORT |= (1<<SEG1);
spi_out(seg[16]);     // all off
SEGPORT &= ~(1<<SEG1);      
SEGPORT |= (1<<SEG2);
spi_out(seg[16]);     // all off
SEGPORT &= ~(1<<SEG2);    
SEGPORT |= (1<<SEG3);
spi_out(seg[16]);     // all off
SEGPORT &= ~(1<<SEG3);        
SEGPORT |= (1<<SEG4); 
spi_out(seg[16]);     // all off
SEGPORT &= ~(1<<SEG4);    

gibt es eine Möglichkeit die ganze Geschichte in einer Schleife zu
behandeln?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn die Konstanten SEG1..SEG4 sich jeweils um 1 unterscheiden, dann
ja:

  int seg;

  for (seg = SEG1; seg <= SEG4; seg++)
  {
    SEGPORT |= (1 << seg);
    spi_out(seg[16]);
    SEGPORT &= (1 << seg);
  }

Das allerdings erzeugt keinen sonderlich effizienten Code, weil die
Shift-Operatoren nicht vom Compiler durch Konstanten ersetzt werden
können. Je nach Prozessor ist eine Shift-Operation recht ineffizient.

Da ließe sich dies hier verwenden:

  int seg;
  int i;

  seg = 1 << SEG1;

  for (i = 0; i < 4; i++)
  {
    SEGPORT |= seg;
    spi_out(seg[16]);
    SEGPORT &= seg;
    seg <<= 1;
  }

Autor: Rahul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
man könnte es so lösen:

unsigned char segs[4] = {SEG1,SEG2,SEG3,SEG4};
unsigned char i;

for(i=0;i<4;i++)
{
  SEGPORT |= (1<<segs[i]);
  spi_out(seg[16]);
  SEGPORT &= (1<<segs[i]);
}

man könnte segs auch so initialisieren:
unsigned char segs[4]= {(1<<SEG1),(1<<SEG2),(1<<SEG3),(1<<SEG4)};

Wenn die Segs in einer bestimmten Reihenfolge angeordent sind, kann man
auch die Laufvariable dafür benutzen...

Autor: Simon K. (simon) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
rufus, du hast zweimal die tilde vergessen ;D

Autor: A.K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder:

#define AlleSEGS (1<<SEG1|1<<SEG2|1<<SEG3|1<<SEG4)

  for (seg = 1<<SEG1; seg & AlleSEGS; seg <<= 1)
  {
    SEGPORT |= seg;
    spi_out(seg[16]);
    SEGPORT &= seg;
  }

Autor: Paul (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uhi, danke! Da sind ja schon einige nette Lösungen bei. Ich werde mir
alle nochmal genauer gucken.
Auf jeden Fall schonmal vielen, vielen Dank!

Autor: Fabian Scheler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Je nach Prozessor ist eine Shift-Operation recht ineffizient."

hm, irgendwie klingt das für mich seltsam. Ich bin jetzt kein
E-Techniker, habe noch nie einen Prozessor gebaut, aber kann ich mir
leider nicht besonders gut vorstellen, was man an einer Shift-Operation
besonders ineffizient machen kann. Kannst du mir das mal erläutern?

Zu den beiden Code-Schnippseln:

  int seg;

  for (seg = SEG1; seg <= SEG4; seg++)
  {
    SEGPORT |= (1 << seg);
    spi_out(seg[16]);
    SEGPORT &= (1 << seg);
  }

und

  int seg;
  int i;

  seg = 1 << SEG1;

  for (i = 0; i < 4; i++)
  {
    SEGPORT |= seg;
    spi_out(seg[16]);
    SEGPORT &= seg;
    seg <<= 1;
  }

also den Compiler, der aus dem obigen Fetzen nicht denselben Code
erzeugt, wie aus dem unteren (wenn man nicht gerade alle Optimierungen
ausschaltet), sollte man wirklich nicht verwenden.

zu guter letzt: hast du dir eigentlich mal angeschaut, was der Compiler
bei höchster Optimierungsstufe, aus dem originär abgebildeten Listing
macht. Ich kann mir vorstellen, dass es Laufzeittechnisch auf jeden
Fall schneller sein sollte und sich von der Codegröße her auch in
Grenzen halten sollte.

Ciao, Fabian

Autor: Μαtthias W. (matthias) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

1<<n ist auf dem AVR architekturbedingt nicht besonders effizient wenn
n nicht zur compilezeit bekannt ist da der AVR nicht über einen
Barrelshifter verfügt, er also pro Takt nur um 1 Bit schieben kann. Ist
n also zur Compilezeit nicht bekannt wird aus 1<<n eine Schleife mit n
Durchläufen. Das will man nicht wirklich haben wenn es sich irgendwie
verhindern läßt.

Matthias

Autor: Fabian Scheler (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, jetzt hat es bezüglich des Shiftens 'Klick' gemacht!

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.