bit twiddling hacks: integers

44
Bit Twiddling Hacks Integers David Barina March 28, 2014 David Barina Bit Hacks March 28, 2014 1 / 41

Upload: david-barina

Post on 07-Aug-2015

94 views

Category:

Science


4 download

TRANSCRIPT

Page 1: Bit Twiddling Hacks: Integers

Bit Twiddling HacksIntegers

David Barina

March 28, 2014

David Barina Bit Hacks March 28, 2014 1 / 41

Page 2: Bit Twiddling Hacks: Integers

Counting bits set: naive

unsigned x;

unsigned c;

for(c = 0; x; x >>= 1)

{c += x & 1;

}

a.k.a. population count, popcount

David Barina Bit Hacks March 28, 2014 2 / 41

Page 3: Bit Twiddling Hacks: Integers

Counting bits set: Kernighan

for(c = 0; x; c++)

{x &= x - 1;

}

David Barina Bit Hacks March 28, 2014 3 / 41

Page 4: Bit Twiddling Hacks: Integers

Counting bits set: Kernighan

x

x-1

x&(x-1)

x

x-1

x&(x-1)

David Barina Bit Hacks March 28, 2014 4 / 41

Page 5: Bit Twiddling Hacks: Integers

Counting bits set: in parallel

x -= x >> 1 & ˜0U/3;

x = (x & ˜0U/15*3) + (x >> 2 & ˜0U/15*3);

x = (x + (x >> 4)) & ˜0U/255*15;

c = (x * (˜0U/255)) >> (sizeof(unsigned) - 1) * CHAR_BIT;

David Barina Bit Hacks March 28, 2014 5 / 41

Page 6: Bit Twiddling Hacks: Integers

Counting bits set

x -= x >> 1 & ˜0U/3;

x = (x & ˜0U/15*3) + (x >> 2 & ˜0U/15*3);

x = (x + (x >> 4)) & ˜0U/255*15;

c = (x * (˜0U/255)) >> (sizeof(unsigned) - 1) * CHAR_BIT;

David Barina Bit Hacks March 28, 2014 6 / 41

Page 7: Bit Twiddling Hacks: Integers

Counting bits set

&~0U/3

x

x>>1

11 - 01 = 10 = 210 - 01 = 01 = 101 - 00 = 01 = 100 - 00 = 00 = 0

-

0..2

David Barina Bit Hacks March 28, 2014 7 / 41

Page 8: Bit Twiddling Hacks: Integers

Counting bits set

x -= x >> 1 & ˜0U/3;

x = (x & ˜0U/15*3) + (x >> 2 & ˜0U/15*3);

x = (x + (x >> 4)) & ˜0U/255*15;

c = (x * (˜0U/255)) >> (sizeof(unsigned) - 1) * CHAR_BIT;

David Barina Bit Hacks March 28, 2014 8 / 41

Page 9: Bit Twiddling Hacks: Integers

Counting bits set

&~0U/15*3

x

x

x>>2

&~0U/15*3

+

0..4

David Barina Bit Hacks March 28, 2014 9 / 41

Page 10: Bit Twiddling Hacks: Integers

Counting bits set

x -= x >> 1 & ˜0U/3;

x = (x & ˜0U/15*3) + (x >> 2 & ˜0U/15*3);

x = (x + (x >> 4)) & ˜0U/255*15;

c = (x * (˜0U/255)) >> (sizeof(unsigned) - 1) * CHAR_BIT;

David Barina Bit Hacks March 28, 2014 10 / 41

Page 11: Bit Twiddling Hacks: Integers

Counting bits set

x

x>>4

&~0U/255*15

+

0..8

David Barina Bit Hacks March 28, 2014 11 / 41

Page 12: Bit Twiddling Hacks: Integers

Counting bits set

x -= x >> 1 & ˜0U/3;

x = (x & ˜0U/15*3) + (x >> 2 & ˜0U/15*3);

x = (x + (x >> 4)) & ˜0U/255*15;

c = (x * (˜0U/255)) >> (sizeof(unsigned) - 1) * CHAR_BIT;

David Barina Bit Hacks March 28, 2014 12 / 41

Page 13: Bit Twiddling Hacks: Integers

Counting bits set

0..8 x

~0U/2551 1 1 1*

0..8 0..8 0..8

0..80..80..80..8

0..80..80..80..8

0..80..80..80..8

0..80..80..80..8

0..32

0..32 >>24

David Barina Bit Hacks March 28, 2014 13 / 41

Page 14: Bit Twiddling Hacks: Integers

Counting bits set

algorithm time

naive 30.943180 nsKernighan 17.374596 nsparallel 4.136793 ns

speedup 7.5×

David Barina Bit Hacks March 28, 2014 14 / 41

Page 15: Bit Twiddling Hacks: Integers

Copy the highest set bit to all of the lower bits

x |= x >> 1;

x |= x >> 2;

x |= x >> 4;

x |= x >> 8;

x |= x >> 16;

a.k.a. copymsb

David Barina Bit Hacks March 28, 2014 15 / 41

Page 16: Bit Twiddling Hacks: Integers

Copy the highest set bit to all of the lower bits

x

x>>1|

x|=x>>1

x>>2|

x|=x>>2

x>>4|

x|=x>>4

David Barina Bit Hacks March 28, 2014 16 / 41

Page 17: Bit Twiddling Hacks: Integers

Copy the highest set bit to all of the lower bits

unsigned shift = 1;

while(shift < sizeof(int) * CHAR_BIT)

{x |= x >> shift;

shift <<= 1;

}

David Barina Bit Hacks March 28, 2014 17 / 41

Page 18: Bit Twiddling Hacks: Integers

Copy the highest set bit to all of the lower bits

algorithm time

unroll 3.687508 nsloop 3.689689 ns

speedup 1.0×

David Barina Bit Hacks March 28, 2014 18 / 41

Page 19: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer

log2(x) = −1 : x < 1

blog2(x)c = dlog2(x + 1)e − 1

dlog2(x)e = blog2(x − 1)c+ 1

David Barina Bit Hacks March 28, 2014 19 / 41

Page 20: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: IEEE double

unsigned x;

unsigned r;

r = (unsigned)ceil(log2((double)x));

r = (unsigned)floor(log2((double)x));

David Barina Bit Hacks March 28, 2014 20 / 41

Page 21: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: naive way (floor)

unsigned r = 0;

while(x >>= 1)

{r++;

}

David Barina Bit Hacks March 28, 2014 21 / 41

Page 22: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: fast way (floor)

unsigned r;

unsigned shift;

r = (x > 0xFFFF) << 4; x >>= r;

shift = (x > 0xFF ) << 3; x >>= shift; r |= shift;

shift = (x > 0xF ) << 2; x >>= shift; r |= shift;

shift = (x > 0x3 ) << 1; x >>= shift; r |= shift;

r |= (x >> 1);

David Barina Bit Hacks March 28, 2014 22 / 41

Page 23: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: fast way (floor)

x

x>0xFFFF

x>>16, r+=16

x>0xFF

x>>8, r+=8

x>0xF

x>>4, r+=4

x>0x3

x>>2, r+=2

x>>1, r+=1

David Barina Bit Hacks March 28, 2014 23 / 41

Page 24: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: popcount (ceil)

x--;

x = copymsb(x); // next pow2 minus 1

r = popcount(x);

David Barina Bit Hacks March 28, 2014 24 / 41

Page 25: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: popcount (ceil)

x

x = copy MSB

r = popcount{r

David Barina Bit Hacks March 28, 2014 25 / 41

Page 26: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: DeBruijn (floor)

static const int MultiplyDeBruijnBitPosition[32] =

{0, 9, 1, 10, 13, 21, 2, 29,

11, 14, 16, 18, 22, 25, 3, 30,

8, 12, 20, 28, 15, 17, 24, 7,

19, 27, 23, 6, 26, 5, 4, 31

};

x = copymsb(x); // next pow2 minus 1

r = MultiplyDeBruijnBitPosition[

(unsigned)(x * 0x07C4ACDDU) >> 27];

David Barina Bit Hacks March 28, 2014 26 / 41

Page 27: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: fast loop (floor)

const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000 };

const unsigned int S[] = { 1, 2, 4, 8, 16 };

register unsigned int r = 0;

for(int i = 4; i >= 0; i--)

{if(x & b[i])

{x >>= S[i];

r |= S[i];

}}

David Barina Bit Hacks March 28, 2014 27 / 41

Page 28: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: table (floor)

static const char LogTable256[256] =

{#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n

-1,

0,

1, 1,

2, 2, 2, 2,

3, 3, 3, 3, 3, 3, 3, 3,

LT(4),

LT(5), LT(5),

LT(6), LT(6), LT(6), LT(6),

LT(7), LT(7), LT(7), LT(7),

LT(7), LT(7), LT(7), LT(7)

#undef LT

};

David Barina Bit Hacks March 28, 2014 28 / 41

Page 29: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer: table (floor)

if(t = x >> 24)

{r = 24 + LogTable256[t];

}else if(t = x >> 16)

{r = 16 + LogTable256[t];

}else if(t = x >> 8)

{r = 8 + LogTable256[t];

}else

{r = LogTable256[x];

}

David Barina Bit Hacks March 28, 2014 29 / 41

Page 30: Bit Twiddling Hacks: Integers

Find the log base 2 of an integer

algorithm floor ceil

double 64.648230 ns 64.569502 nsnaive 20.249388 ns 20.179684 nsfast 12.542725 ns 12.199326 nspopcount 8.794856 ns 8.409071 nsDeBruijn 4.519947 ns 4.809108 nsfast loop 3.784315 ns 3.716202 nstable 1.834092 ns 1.835536 ns

speedup > 35×

David Barina Bit Hacks March 28, 2014 30 / 41

Page 31: Bit Twiddling Hacks: Integers

Next power of 2: copymsb

x--;

x = copymsb(x);

x++;

David Barina Bit Hacks March 28, 2014 31 / 41

Page 32: Bit Twiddling Hacks: Integers

Next power of 2: table

x = 1 << ceil_log2(x);

David Barina Bit Hacks March 28, 2014 32 / 41

Page 33: Bit Twiddling Hacks: Integers

Next power of 2

algorithm time

copymsb 3.976506 nslog2 table 2.169806 ns

speedup > 1.8×

David Barina Bit Hacks March 28, 2014 33 / 41

Page 34: Bit Twiddling Hacks: Integers

Is power of 2

if( 0 == (x & (x-1)) )

{// ...

}

David Barina Bit Hacks March 28, 2014 34 / 41

Page 35: Bit Twiddling Hacks: Integers

Select minimum, maximum: naive

(x < y) ? x : y

(x > y) ? x : y

David Barina Bit Hacks March 28, 2014 35 / 41

Page 36: Bit Twiddling Hacks: Integers

Select minimum, maximum: xor

(((x-y) >> (sizeof(int)*CHAR_BIT-1)) & (xˆy)) ˆ y

(((x-y) >> (sizeof(int)*CHAR_BIT-1)) & (yˆx)) ˆ x

x = y ˆ (xˆy)

y = y ˆ 0

(-z) >> 31 = 0xffffffff

(+z) >> 31 = 0x00000000

David Barina Bit Hacks March 28, 2014 36 / 41

Page 37: Bit Twiddling Hacks: Integers

Select minimum, maximum

algorithm min max

naive 1.509076 ns 1.503108 nsxor 2.035053 ns 1.847343 ns

speedup 0.7×

David Barina Bit Hacks March 28, 2014 37 / 41

Page 38: Bit Twiddling Hacks: Integers

Absolute value (32-bit)

// stdlib.h

printf("%i\n", abs(+1000000000));printf("%i\n", abs(-1000000000));printf("%i\n", abs(-2147483648));

1000000000

1000000000

-2147483648

David Barina Bit Hacks March 28, 2014 38 / 41

Page 39: Bit Twiddling Hacks: Integers

Absolute value (32-bit)

// stdlib.h

printf("%i\n", abs(+1000000000));printf("%i\n", abs(-1000000000));printf("%i\n", abs(-2147483648));

1000000000

1000000000

-2147483648

David Barina Bit Hacks March 28, 2014 38 / 41

Page 40: Bit Twiddling Hacks: Integers

Negate (32-bit)

// negate all bits and add "1"

printf("%i\n", negate(+1000000000));printf("%i\n", negate(-1000000000));printf("%i\n", negate(-2147483648));

-1000000000

1000000000

-2147483648

David Barina Bit Hacks March 28, 2014 39 / 41

Page 41: Bit Twiddling Hacks: Integers

Negate (32-bit)

// negate all bits and add "1"

printf("%i\n", negate(+1000000000));printf("%i\n", negate(-1000000000));printf("%i\n", negate(-2147483648));

-1000000000

1000000000

-2147483648

David Barina Bit Hacks March 28, 2014 39 / 41

Page 42: Bit Twiddling Hacks: Integers

Overflow (32-bit and 64-bit)

printf("%i\n", (int)+2147483648); // long int => intprintf("%li\n", +2147483648); // long int

-2147483648

2147483648

David Barina Bit Hacks March 28, 2014 40 / 41

Page 43: Bit Twiddling Hacks: Integers

Overflow (32-bit and 64-bit)

printf("%i\n", (int)+2147483648); // long int => intprintf("%li\n", +2147483648); // long int

-2147483648

2147483648

David Barina Bit Hacks March 28, 2014 40 / 41

Page 44: Bit Twiddling Hacks: Integers

Sources

x86, Intel Core2 Quad @ 2.00 GHz

gcc 4.8 -O3

https://www.google.com/?q=Bit+Twiddling

http://graphics.stanford.edu/˜seander/bithacks.html

http://www.fefe.de/intof.html

David Barina Bit Hacks March 28, 2014 41 / 41