Search code examples
cbitvector

Fast way to know compute parity of bitvector


I am working with bitvectors in C. My bitvectors are unsigned long long's. For a large number of vectors I need to know if the parity, i.e. the number of bits that are 1, is even or odd.

The exact value is not important, just the parity. I was wondering if there is anything faster than calculating the number of ones and checking. I tried to think of something, but couldn't find anything.

A short example of how I want this to work:

void checkIntersection(unsigned long long int setA, unsigned long long int setB){
    if(isEven(setA & setB)){
        //do something
    }
}

Solution

  • With divide and conquer technique:

    uint64_t a = value;
    a ^= (a >> 32);            // Fold the 32 MSB over the 32 LSB
    a ^= (a >> 16);            // reducing the problem by 50%
    a ^= (a >> 8);             // <-- this can be a good break even point
    ..
    return lookup_table[a & 0xff];  // 16 or 256 entries are typically good
    ..
    

    Folding procedure can be applied until the end:

    a ^= (a >> 1);
    return a & 1;
    

    In IA the Parity flag can be directly retrieved after the reduction to 8 bits.

    a ^= (a >> 4); makes another good point to stop dividing, since some processor architectures can provide parallel Look Up Tables uint8_t LUT[16] embedded into XXM (or NEON) registers. Or simply the potential cache misses of 256-entry LUT's can simply overweight the computational task of one extra round. It's naturally best to measure which LUT size is optimal in a given architecture.

    This last table consists actually of 16 bits only and can be emulated with the sequence:

    return ((TRUTH_TABLE_FOR_PARITY) >> (a & 15)) & 1;
    

    where bit N of the magic constant above encodes the boolean value for Parity(N).