Forum: Compiler & IDEs Shuffelbits in einem Byte


von Olaf (Gast)


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

von Random .. (thorstendb) Benutzerseite


Lesenswert?

im Cortex-M3:
Reverse bit (RBIT), dann reverse byte (REV)

VG,
/th.

von Karl H. (kbuchegg)


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.

von Peter (Gast)


Lesenswert?

wenn du genug speicher hast

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

return map[ value ];


schneller geht es nicht.

von (prx) A. K. (prx)


Lesenswert?


von (prx) A. K. (prx)


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.

von Olaf (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.