code effizienter gestalten

Gast #270730
Lesenswert?
• ▲
▼
Abend!
Ich stehe zur Zeit vor folgendem Problem.Hier erstmal der Code
1
SEGPORT |= (1<<SEG1);
2
spi_out(seg[16]);     // all off
3
SEGPORT &= ~(1<<SEG1);      
4
SEGPORT |= (1<<SEG2);
5
spi_out(seg[16]);     // all off
6
SEGPORT &= ~(1<<SEG2);    
7
SEGPORT |= (1<<SEG3);
8
spi_out(seg[16]);     // all off
9
SEGPORT &= ~(1<<SEG3);        
10
SEGPORT |= (1<<SEG4); 
11
spi_out(seg[16]);     // all off
12
SEGPORT &= ~(1<<SEG4);

gibt es eine Möglichkeit die ganze Geschichte in einer Schleife zu
behandeln?
Persönliche Seite #270731
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;
  }
Gast #270732
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...
Gast #270736
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
Persönliche Seite #270737
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

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 20 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.