www.mikrocontroller.net

Forum: Compiler & IDEs Shuffelbits in einem Byte


Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe eine kleine Denksportaufgabe. Ich benoetige eine
Routine die alle Bits eines Bytes vertauscht. Also Bit7 wird
Bit0, bit6 nach bit1, bit0 nach bit7 usw.

Das hier ist mir eingefallen:

unsigned char shufflepixel(unsigned char pixel)
{
  return (
  ((pixel&0x80)>>7) | ((pixel&0x40)>>5) | ((pixel&0x20)>>3) | 
((pixel&0x10)>>1) |
  ((pixel&0x08)<<1) | ((pixel&0x04)<<3) | ((pixel&0x02)<<5) | 
((pixel&0x01)<<7)
    );

}

Das funktioniert natuerlich, aber da ich das brauche um bilder
in ein Format umzurechnen wie ein LCD es gerne haette, waere es
schoener wenn das ganze etwas schneller ginge. Vielleicht
kenn einer einen eleganten Trick?

Olaf

Autor: Random ... (thorstendb) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
im Cortex-M3:
Reverse bit (RBIT), dann reverse byte (REV)

VG,
/th.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hmm.
Ohne das mit einem Profiler verifiziert zu haben.

Was hältst du von einer Tabelle, mit der du für ein Nibble des jeweils 
gespiegelte Nibble erhältst.

Das Byte in die Nibbles zerlegen, aus der Tabelle das 'Spiegelnibble' 
holen und die beiden Teilergebnisse gespiegelt zusammenbauen.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wenn du genug speicher hast

static unsigned char map[256] = { 128, 64, 192 ... };

return map[ value ];


schneller geht es nicht.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sowas hängt auch dann vom Prozessor ab, wenn der kein RBIT hat. So kann 
man bei AVRs in 2 Befehlen ein Bit testen und bedingt setzen, oder auch 
einfach über das T-Bit kopieren. Solche Schiebeoperationen sind bei AVRs 
wie auch jedem anderen Prozessor, der nur einzelbitweise schieben kann, 
jedoch sehr teuer, sollte man also vermeiden.

Je nach Prozessor kann es also weit sinnvoller so aussehen:
   r = 0;
   if (pixel & 0x01) r |= 0x80;
   if (pixel & 0x02) r |= 0x40;
   ...
Wenn der Compiler daraus das Richtige macht.

Tabelle ist natürlich dennoch schneller.

Autor: Olaf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Tabelle ist natürlich dennoch schneller.

Klar, aber das ist so die Holzhammermethode.

So rein optisch gefallen mir die beiden hier am besten:

  return( ((pixel * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL 
>> 32);
  return(((pixel * 0x0802LU & 0x22110LU) | (pixel * 0x8020LU & 
0x88440LU)) * 0x10101LU >> 16);

Ich muss morgen mal ausprobieren was am schnellsten ist. CPU ist im 
uebrigen kein AVR sondern ein R32C116. Da kann ich mir schon erlauben 
mit breiteren Datentypen rumzumachen.

Olaf

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.