bit fields - Is this the most optimal way? C bitfields -
i made function set or clear specific number of bits in dword. function works. don't need making work. however, wondering if method i've chosen fastest possible way.
it's rather hard me explain how works. there 2 arrays containing dwords filled bits on left , right side of dword (with binary 1's). makes mask bits filled except ones want set or clear, , sets them bitwise operators based on mask. seems rather complicated such simple task, seems fastest way come with. it's faster setting them bit bit.
static dword __dwfilledbitsright[] = { 0x0, 0x1, 0x3, 0x7, 0xf, 0x1f, 0x3f, 0x7f, 0xff, 0x1ff, 0x3ff, 0x7ff, 0xfff, 0x1fff, 0x3fff, 0x7fff, 0xffff, 0x1ffff, 0x3ffff, 0x7ffff, 0xfffff, 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff, 0x1ffffff, 0x3ffffff, 0x7ffffff, 0xfffffff, 0x1fffffff, 0x3fffffff, 0x7fffffff, 0xffffffff }; static dword __dwfilledbitsleft[] = { 0x0, 0x80000000, 0xc0000000, 0xe0000000, 0xf0000000, 0xf8000000, 0xfc000000, 0xfe000000, 0xff000000, 0xff800000, 0xffc00000, 0xffe00000, 0xfff00000, 0xfff80000, 0xfffc0000, 0xfffe0000, 0xffff0000, 0xffff8000, 0xffffc000, 0xffffe000, 0xfffff000, 0xfffff800, 0xfffffc00, 0xfffffe00, 0xffffff00, 0xffffff80, 0xffffffc0, 0xffffffe0, 0xfffffff0, 0xfffffff8, 0xfffffffc, 0xfffffffe, 0xffffffff }; // nstartbitfromleft must between 1 , 32... // 1 bit farthest left (actual bit 31) // 32 bit farthest right (actual bit 0) inline void __filldwordbits(dword *p, int nstartbitfromleft, int nbits, bool bset) { dword dwleftmask = __dwfilledbitsleft[nstartbitfromleft - 1]; // mask data on left of bits want dword dwrightmask = __dwfilledbitsright[33 - (nstartbitfromleft + nbits)]; // mask data on right of bits want dword dwbitmask = ~(dwleftmask | dwrightmask); // mask bits want dword dworiginal = *p; if(bset) *p = (dworiginal & dwleftmask) | (dworiginal & dwrightmask) | (0xffffffff & dwbitmask); else *p = (dworiginal & dwleftmask) | (dworiginal & dwrightmask) | 0; }
how about:
// create mask of correct length, , shift correct position dword mask = ((1ull << nbits) - 1) << pos; // apply mask (or inverse) if (bset) { *p |= mask; } else { *p &= ~mask; }
it's pretty simple bitwise operations faster table lookup on modern processor.
note: depending on relationship between dword
, long long
on platform, may need special handling case nbits == sizeof(dword)*8
. or if nbits==0
not possibility, dword mask = ((2ull << (nbits - 1)) - 1) << pos;
.
update: it's been mentioned if
potentially slow, true. here's replacement it, you'd need measure see if it's faster in practice.
// bit hacky, aim 0x00000000 or 0xffffffff // (relies on two's-complement representation) dword blanket = bset - 1; // use blanket override 1 or other masking operation *p |= (blanket | mask); *p &= ~(blanket & mask);
Comments
Post a Comment