While I don't think this is a good idea, one solution would be to have pre-allocated buckets of various sizes of log 2 , a silly pseudocode:
class Allocator { void* malloc(size_t size) { int bucket = log2(size + sizeof(int)); int* pointer = reinterpret_cast<int*>(m_buckets[bucket].back()); m_buckets[bucket].pop_back(); *pointer = bucket;
(Of course, you will also replace std::vector with a simple array + counter).
EDIT: To make this reliable (i.e. handle the situation when the bucket is empty), you will need to add some form of branching.
EDIT2: Here's a little undisclosed log2 function:
//returns the smallest x such that value <= (1 << x) int log2(int value) { union Foo { int x; float y; } foo; foo.y = value - 1; return ((foo.x & (0xFF << 23)) >> 23) - 126; //Extract exponent (base 2) of floating point number }
This gives the correct result for allocations of <33554432 bytes. If you need a large allocation, you will have to switch to paired.
Here's a link on how floating point numbers are represented in memory.
Andreas Brinck
source share