Find the first zero in a bitarray

前端 未结 3 1040
闹比i
闹比i 2020-12-18 12:02

I have a bitmap

uint64_t bitmap[10000] 

to keep track of the resources allocated in the system. Now the question is how do efficiently I

相关标签:
3条回答
  • 2020-12-18 12:47

    If you are using a 32 bit cpu then you do not want to do that. Rather use arrays of 32 bit ints. The loop over the array will be faster.

    Also you can encode every value for 1 byte and then pre-store which is the first bit set in the byte. So when you find an integer that is not all 0xFFFFFFFF you can then simply compare the bytes. If the first byte is not 0xFF then it is in that byte and so on.

    So if a byte is not 0xFF it means it is one of the 255 possible values for the byte. And each value has a first bit set.

    Another way of looking at the problem is to divide it up into chunks if possible. I do not know what your resource is so I cannot say.

    Also consider that on the previous scan for the unset bit that it looped forward. If you store the index of the previous result, then you can simply start from the same index on the next search. Call this index the pos and use it each time.

    You can also create a small array of "free" indexes each time you set a bit to zero, so when your "pos" reaches the end of the array just start again from one of the saved indexes.

    In other words you really do not want to be running such a long loop each time. That is your problem, not the final instruction to get the bit. Use the index tracking as outlined above and it will go hundreds of times faster.

    0 讨论(0)
  • 2020-12-18 12:51

    I'm not sure how you'd get much faster than this, but I'm open to being proven wrong:

    uint64_t bitmap[10000];
    unsigned int i;
    for (i = 0; i < (sizeof(bitmap) / sizeof(*bitmap)) && 0xFFFFFFFFFFFFFFFF == bitmap[i]; ++i);
    const int bitInWord = ffsll(bitmap[i]);
    const unsigned int firstZeroBit = bitInWord ? i * sizeof(*bitmap) * CHAR_BIT + bitInWord : 0;
    
    0 讨论(0)
  • 2020-12-18 13:00

    You can maintain a tree of bitmaps to efficiently find the lowest bit set. On a 64-bit CPU, you only have to have a tree depth of 3 to track 4096 64-bit elements -- that means only using three ffsll calls.

    Basically, this works by dividing your array into 64-word chunks and assigning one 64-bit index to each chunk. A bit of the index word is set iff the corresponding bitset word has all bits set. When you change a bit in the bitset, you adjust the corresponding index word.

    You can then build another index array on top to form a tree.

    It requires a little extra work on every bit change, but the total amount of extra work (and storage) is negligible compared to the savings you get from not having to linearly search your bitset when you need a free bit.

    0 讨论(0)
提交回复
热议问题