Added 96-byte FastAllocator

Since storage queue nodes account for a large portion of memory usage,
we can save space by only allocating 96 bytes instead of 128 bytes for
each node.
This commit is contained in:
Trevor Clinkenbeard 2019-03-20 10:11:12 -07:00
parent 797ccea546
commit 007abbc45b
5 changed files with 24 additions and 16 deletions

View File

@ -483,7 +483,7 @@ public:
return r->second;
}
static const int overheadPerItem = 128*4;
static const int overheadPerItem = 96*4;
struct iterator;
VersionedMap() : oldestVersion(0), latestVersion(0) {

View File

@ -3693,7 +3693,7 @@ void versionedMapTest() {
printf("SS Ptree node is %zu bytes\n", sizeof( StorageServer::VersionedData::PTreeT ) );
const int NSIZE = sizeof(VersionedMap<int,int>::PTreeT);
const int ASIZE = NSIZE<=64 ? 64 : NextPowerOfTwo<NSIZE>::Result;
const int ASIZE = NSIZE<=64 ? 64 : NextFastAllocatedSize<NSIZE>::Result;
auto before = FastAllocator< ASIZE >::getTotalMemory();

View File

@ -222,7 +222,8 @@ struct ArenaBlock : NonCopyable, ThreadSafeReferenceCounted<ArenaBlock>
}
if (reqSize < LARGE) {
if (reqSize <= 128) { b = (ArenaBlock*)FastAllocator<128>::allocate(); b->bigSize = 128; INSTRUMENT_ALLOCATE("Arena128"); }
if (reqSize <= 96) { b = (ArenaBlock*)FastAllocator<96>::allocate(); b->bigSize = 96; INSTRUMENT_ALLOCATE("Arena96"); }
else if (reqSize <= 128) { b = (ArenaBlock*)FastAllocator<128>::allocate(); b->bigSize = 128; INSTRUMENT_ALLOCATE("Arena128"); }
else if (reqSize <= 256) { b = (ArenaBlock*)FastAllocator<256>::allocate(); b->bigSize = 256; INSTRUMENT_ALLOCATE("Arena256"); }
else if (reqSize <= 512) { b = (ArenaBlock*)FastAllocator<512>::allocate(); b->bigSize = 512; INSTRUMENT_ALLOCATE("Arena512"); }
else if (reqSize <= 1024) { b = (ArenaBlock*)FastAllocator<1024>::allocate(); b->bigSize = 1024; INSTRUMENT_ALLOCATE("Arena1024"); }
@ -264,7 +265,8 @@ struct ArenaBlock : NonCopyable, ThreadSafeReferenceCounted<ArenaBlock>
else if (tinySize <= 32) { FastAllocator<32>::release(this); INSTRUMENT_RELEASE("Arena32"); }
else { FastAllocator<64>::release(this); INSTRUMENT_RELEASE("Arena64"); }
} else {
if (bigSize <= 128) { FastAllocator<128>::release(this); INSTRUMENT_RELEASE("Arena128"); }
if (bigSize <= 96) { FastAllocator<96>::release(this); INSTRUMENT_RELEASE("Arena96"); }
else if (bigSize <= 128) { FastAllocator<128>::release(this); INSTRUMENT_RELEASE("Arena128"); }
else if (bigSize <= 256) { FastAllocator<256>::release(this); INSTRUMENT_RELEASE("Arena256"); }
else if (bigSize <= 512) { FastAllocator<512>::release(this); INSTRUMENT_RELEASE("Arena512"); }
else if (bigSize <= 1024) { FastAllocator<1024>::release(this); INSTRUMENT_RELEASE("Arena1024"); }

View File

@ -219,14 +219,15 @@ static int64_t getSizeCode(int i) {
case 16: return 1;
case 32: return 2;
case 64: return 3;
case 128: return 4;
case 256: return 5;
case 512: return 6;
case 1024: return 7;
case 2048: return 8;
case 4096: return 9;
case 8192: return 10;
default: return 11;
case 96: return 4;
case 128: return 5;
case 256: return 6;
case 512: return 7;
case 1024: return 8;
case 2048: return 9;
case 4096: return 10;
case 8192: return 11;
default: return 12;
}
}
@ -475,6 +476,7 @@ void releaseAllThreadMagazines() {
FastAllocator<16>::releaseThreadMagazines();
FastAllocator<32>::releaseThreadMagazines();
FastAllocator<64>::releaseThreadMagazines();
FastAllocator<96>::releaseThreadMagazines();
FastAllocator<128>::releaseThreadMagazines();
FastAllocator<256>::releaseThreadMagazines();
FastAllocator<512>::releaseThreadMagazines();
@ -490,6 +492,7 @@ int64_t getTotalUnusedAllocatedMemory() {
unusedMemory += FastAllocator<16>::getApproximateMemoryUnused();
unusedMemory += FastAllocator<32>::getApproximateMemoryUnused();
unusedMemory += FastAllocator<64>::getApproximateMemoryUnused();
unusedMemory += FastAllocator<96>::getApproximateMemoryUnused();
unusedMemory += FastAllocator<128>::getApproximateMemoryUnused();
unusedMemory += FastAllocator<256>::getApproximateMemoryUnused();
unusedMemory += FastAllocator<512>::getApproximateMemoryUnused();
@ -504,6 +507,7 @@ int64_t getTotalUnusedAllocatedMemory() {
template class FastAllocator<16>;
template class FastAllocator<32>;
template class FastAllocator<64>;
template class FastAllocator<96>;
template class FastAllocator<128>;
template class FastAllocator<256>;
template class FastAllocator<512>;

View File

@ -156,7 +156,7 @@ int64_t getTotalUnusedAllocatedMemory();
void setFastAllocatorThreadInitFunction( void (*)() ); // The given function will be called at least once in each thread that allocates from a FastAllocator. Currently just one such function is tracked.
template<int X>
class NextPowerOfTwo {
class NextFastAllocatedSize {
static const int A = X-1;
static const int B = A | (A>>1);
static const int C = B | (B>>2);
@ -164,7 +164,7 @@ class NextPowerOfTwo {
static const int E = D | (D>>8);
static const int F = E | (E>>16);
public:
static const int Result = F+1;
static const int Result = (X > 64 && X <= 96) ? 96 : F+1;
};
template <class Object>
@ -173,13 +173,13 @@ public:
static void* operator new(size_t s) {
if (s != sizeof(Object)) abort();
INSTRUMENT_ALLOCATE(typeid(Object).name());
void* p = FastAllocator<sizeof(Object)<=64 ? 64 : NextPowerOfTwo<sizeof(Object)>::Result>::allocate();
void* p = FastAllocator<sizeof(Object)<=64 ? 64 : NextFastAllocatedSize<sizeof(Object)>::Result>::allocate();
return p;
}
static void operator delete(void* s) {
INSTRUMENT_RELEASE(typeid(Object).name());
FastAllocator<sizeof(Object)<=64 ? 64 : NextPowerOfTwo<sizeof(Object)>::Result>::release(s);
FastAllocator<sizeof(Object)<=64 ? 64 : NextFastAllocatedSize<sizeof(Object)>::Result>::release(s);
}
// Redefine placement new so you can still use it
static void* operator new( size_t, void* p ) { return p; }
@ -190,6 +190,7 @@ static void* allocateFast(int size) {
if (size <= 16) return FastAllocator<16>::allocate();
if (size <= 32) return FastAllocator<32>::allocate();
if (size <= 64) return FastAllocator<64>::allocate();
if (size <= 96) return FastAllocator<96>::allocate();
if (size <= 128) return FastAllocator<128>::allocate();
if (size <= 256) return FastAllocator<256>::allocate();
if (size <= 512) return FastAllocator<512>::allocate();
@ -200,6 +201,7 @@ static void freeFast(int size, void* ptr) {
if (size <= 16) return FastAllocator<16>::release(ptr);
if (size <= 32) return FastAllocator<32>::release(ptr);
if (size <= 64) return FastAllocator<64>::release(ptr);
if (size <= 96) return FastAllocator<96>::release(ptr);
if (size <= 128) return FastAllocator<128>::release(ptr);
if (size <= 256) return FastAllocator<256>::release(ptr);
if (size <= 512) return FastAllocator<512>::release(ptr);