2010-12-07 11 views
3

Ich versuche nur, ultra-schnelle Funktionen zum Setzen und Abrufen von Bits in uint32-Arrays zu entwickeln. Zum Beispiel können Sie "Bit 1035 auf 1 setzen" sagen. Dann wird das mit 1035/32 indizierte uint32 mit der Bitposition 1035% 32 verwendet. Besonders gefällt mir die Verzweigung in der setbit-Funktion nicht.Schnellste Möglichkeiten, ein Bit zu setzen und zu bekommen

Hier ist mein Ansatz:

void SetBit(uint32* data, const uint32 bitpos, const bool newval) 
{ 
    if (newval) 
    { 
     //Set On 
     data[bitpos >> 5u] |= (1u << (31u - (bitpos & 31u))); 
     return; 
    } 
    else 
    { 
     //Set Off 
     data[bitpos >> 5u] &= ~(1u << (31u - (bitpos & 31u))); 
     return; 
    } 
} 

und

bool GetBit(const uint32* data, const uint32 bitpos) 
{ 
    return (data[bitpos >> 5u] >> (31u - (bitpos & 31u))) & 1u; 
} 

Thank you!

+1

Welche Architektur

Zweitens Sie unter Verwendung eines clever bit hack bekommen kann den Zweig los? Welche Sprache? Was gibt der Compiler jetzt aus? Sie könnten feststellen, dass es schon ziemlich schnell ist. –

+0

Es ist x86 (32 Bit). In der Tat ist es schon ziemlich schnell, aber ich denke - besonders in der Setbit-Funktion könnte ich immer noch schneller sein ... – vls

+0

Ihr SetBit ist wirklich ein FlipBit, es scheint, dass Sie wahrscheinlich einfach xor (typischerweise das ~ = Operator). –

Antwort

0

Zuerst würde ich die 31u - ... aus allen Ausdrücken fallen lassen: alles, was es tut, ist die Bits in Ihrer privaten Darstellung des Bit-Sets neu zu ordnen, so dass Sie diese Reihenfolge umdrehen können, ohne dass es jemand merkt.

void SetBit(uint32* data, const uint32 bitpos, const bool f) 
{ 
    uint32 &w = data[bitpos >> 5u]; 
    uint32 m = 1u << (bitpos & 31u); 
    w = (w & ~m) | (-f & m); 
} 

Drittens können Sie vereinfachen Ihre Getter, indem man den Compiler tun, um die Umwandlung:

bool GetBit(const uint32* data, const uint32 bitpos) 
{ 
    return data[bitpos >> 5u] & (1u << (bitpos & 31u)); 
}