mirror of
https://review.haiku-os.org/haiku
synced 2024-11-23 15:28:58 +01:00
BFS: Optimize the search for the next free block.
We already started at the first-free in the block bitmap, but after that we would just check individual bits as we went along. Now we skip forwards to the next free block when encountering a used block, by comparing to UINT32_MAX (all blocks used) and using ffs() with a bitwise NOT (to find the first unused block in a chunk.) This will benefit fragmented partitions more than non-fragmented ones. I didn't see a significant speedup on my compile benchmark in a VM. Fixes #18929. X512 tested this patch and confirmed it reduces CPU usage on a partition that he saw long times spent in AllocateBlocks on. Change-Id: If71b5e24c585c2cc08879c8aefc80af8ae7da91f Reviewed-on: https://review.haiku-os.org/c/haiku/+/8186 Reviewed-by: waddlesplash <waddlesplash@gmail.com> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
6e690f7d11
commit
87a66be550
@ -174,6 +174,7 @@ public:
|
||||
inline void Allocate(uint16 start, uint16 numBlocks);
|
||||
inline void Free(uint16 start, uint16 numBlocks);
|
||||
inline bool IsUsed(uint16 block);
|
||||
inline uint32 NextFree(uint16 startBlock);
|
||||
|
||||
status_t SetTo(AllocationGroup& group, uint16 block);
|
||||
status_t SetToWritable(Transaction& transaction, AllocationGroup& group,
|
||||
@ -270,6 +271,30 @@ AllocationBlock::IsUsed(uint16 block)
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
AllocationBlock::NextFree(uint16 startBlock)
|
||||
{
|
||||
// Set all bits below the start block in the current chunk, to ignore them.
|
||||
uint32 ignoreNext = (1UL << (startBlock % 32)) - 1;
|
||||
|
||||
for (uint32 offset = ROUNDDOWN(startBlock, 32);
|
||||
offset < fNumBits; offset += 32) {
|
||||
uint32 chunk = Chunk(offset >> 5);
|
||||
chunk |= ignoreNext;
|
||||
ignoreNext = 0;
|
||||
|
||||
if (chunk == UINT32_MAX)
|
||||
continue;
|
||||
uint32 result = offset + ffs(~chunk) - 1;
|
||||
if (result >= fNumBits)
|
||||
break;
|
||||
return result;
|
||||
}
|
||||
|
||||
return fNumBits;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AllocationBlock::Allocate(uint16 start, uint16 numBlocks)
|
||||
{
|
||||
@ -838,6 +863,12 @@ BlockAllocator::AllocateBlocks(Transaction& transaction, int32 groupIndex,
|
||||
block = group.NumBitmapBlocks();
|
||||
break;
|
||||
}
|
||||
|
||||
// Advance the current bit to one before the next free (or last) bit,
|
||||
// so that the next loop iteration will check the next free bit.
|
||||
const uint32 nextFreeOffset = cached.NextFree(bit) - bit;
|
||||
bit += nextFreeOffset - 1;
|
||||
currentBit += nextFreeOffset - 1;
|
||||
}
|
||||
currentBit++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user