Removed DecommitAll strategy

The DecommitAll strategy performs badly.  We are not
functionally testing it, and it does not seem investing in it due to its
performance.
This commit is contained in:
Matthew Parkinson
2020-01-29 11:58:57 +00:00
parent a2b56f9740
commit 2e4b289991
5 changed files with 18 additions and 56 deletions

View File

@@ -930,8 +930,7 @@ namespace snmalloc
if (super != nullptr)
{
Slab* slab =
super->alloc_short_slab(sizeclass, large_allocator.memory_provider);
Slab* slab = super->alloc_short_slab(sizeclass);
assert(super->is_full());
return slab;
}
@@ -941,8 +940,7 @@ namespace snmalloc
if ((allow_reserve == NoReserve) && (super == nullptr))
return nullptr;
Slab* slab =
super->alloc_short_slab(sizeclass, large_allocator.memory_provider);
Slab* slab = super->alloc_short_slab(sizeclass);
reposition_superslab(super);
return slab;
}
@@ -952,8 +950,7 @@ namespace snmalloc
if ((allow_reserve == NoReserve) && (super == nullptr))
return nullptr;
Slab* slab =
super->alloc_slab(sizeclass, large_allocator.memory_provider);
Slab* slab = super->alloc_slab(sizeclass);
reposition_superslab(super);
return slab;
}
@@ -1074,7 +1071,7 @@ namespace snmalloc
SlabList* sl = &small_classes[sizeclass];
Slab* slab = Metaslab::get_slab(p);
Superslab::Action a =
slab->dealloc_slow(sl, super, p, large_allocator.memory_provider);
slab->dealloc_slow(sl, super, p);
if (likely(a == Superslab::NoSlabReturn))
return;
stats().sizeclass_dealloc_slab(sizeclass);
@@ -1191,7 +1188,7 @@ namespace snmalloc
{
MEASURE_TIME(medium_dealloc, 4, 16);
stats().sizeclass_dealloc(sizeclass);
bool was_full = slab->dealloc(p, large_allocator.memory_provider);
bool was_full = slab->dealloc(p);
#ifdef CHECK_CLIENT
if (!is_multiple_of_sizeclass(

View File

@@ -68,10 +68,6 @@ namespace snmalloc
* Decommit superslabs when they are entirely empty.
*/
DecommitSuper,
/**
* Decommit all slabs once they are empty.
*/
DecommitAll,
/**
* Decommit superslabs only when we are informed of memory pressure by the
* OS, do not decommit anything in normal operation.

View File

@@ -87,16 +87,13 @@ namespace snmalloc
assert(is_aligned_block<OS_PAGE_SIZE>(p, OS_PAGE_SIZE));
size = bits::align_up(size, OS_PAGE_SIZE);
if constexpr (decommit_strategy == DecommitAll)
memory_provider.template notify_using<zero_mem>(p, size);
else if constexpr (zero_mem == YesZero)
if constexpr (zero_mem == YesZero)
memory_provider.template zero<true>(p, size);
return p;
}
template<typename MemoryProvider>
bool dealloc(void* p, MemoryProvider& memory_provider)
bool dealloc(void* p)
{
assert(head > 0);
@@ -105,9 +102,6 @@ namespace snmalloc
free++;
stack[--head] = pointer_to_index(p);
if constexpr (decommit_strategy == DecommitAll)
memory_provider.notify_not_using(p, sizeclass_to_size(sizeclass));
return was_full;
}

View File

@@ -178,9 +178,8 @@ namespace snmalloc
// This does not need to remove the "use" as done by the fast path.
// Returns a complex return code for managing the superslab meta data.
// i.e. This deallocation could make an entire superslab free.
template<typename MemoryProvider>
SNMALLOC_SLOW_PATH typename Superslab::Action dealloc_slow(
SlabList* sl, Superslab* super, void* p, MemoryProvider& memory_provider)
SlabList* sl, Superslab* super, void* p)
{
Metaslab& meta = super->get_meta(this);
@@ -191,9 +190,9 @@ namespace snmalloc
{
// Dealloc on the superslab.
if (is_short())
return super->dealloc_short_slab(memory_provider);
return super->dealloc_short_slab();
return super->dealloc_slab(this, memory_provider);
return super->dealloc_slab(this);
}
// Update the head and the sizeclass link.
uint16_t index = pointer_to_index(p);
@@ -212,10 +211,11 @@ namespace snmalloc
sl->remove(meta.get_link(this));
if (is_short())
return super->dealloc_short_slab(memory_provider);
return super->dealloc_short_slab();
return super->dealloc_slab(this, memory_provider);
return super->dealloc_slab(this);
}
bool is_short()
{
return Metaslab::is_short(this);

View File

@@ -154,29 +154,21 @@ namespace snmalloc
return meta[slab_to_index(slab)];
}
template<typename MemoryProvider>
Slab*
alloc_short_slab(sizeclass_t sizeclass, MemoryProvider& memory_provider)
Slab* alloc_short_slab(sizeclass_t sizeclass)
{
if ((used & 1) == 1)
return alloc_slab(sizeclass, memory_provider);
return alloc_slab(sizeclass);
meta[0].allocated = 1;
meta[0].head = nullptr;
meta[0].sizeclass = static_cast<uint8_t>(sizeclass);
meta[0].link = get_initial_offset(sizeclass, true);
{
memory_provider.template notify_using<NoZero>(
pointer_offset(this, OS_PAGE_SIZE), SLAB_SIZE - OS_PAGE_SIZE);
}
used++;
return (Slab*)this;
}
template<typename MemoryProvider>
Slab* alloc_slab(sizeclass_t sizeclass, MemoryProvider& memory_provider)
Slab* alloc_slab(sizeclass_t sizeclass)
{
uint8_t h = head;
Slab* slab = pointer_cast<Slab>(
@@ -192,17 +184,11 @@ namespace snmalloc
head = h + n + 1;
used += 2;
if constexpr (decommit_strategy == DecommitAll)
{
memory_provider.template notify_using<NoZero>(slab, SLAB_SIZE);
}
return slab;
}
// Returns true, if this alters the value of get_status
template<typename MemoryProvider>
Action dealloc_slab(Slab* slab, MemoryProvider& memory_provider)
Action dealloc_slab(Slab* slab)
{
// This is not the short slab.
uint8_t index = static_cast<uint8_t>(slab_to_index(slab));
@@ -214,9 +200,6 @@ namespace snmalloc
bool was_almost_full = is_almost_full();
used -= 2;
if constexpr (decommit_strategy == DecommitAll)
memory_provider.notify_not_using(slab, SLAB_SIZE);
assert(meta[index].is_unused());
if (was_almost_full || is_empty())
return StatusChange;
@@ -225,16 +208,8 @@ namespace snmalloc
}
// Returns true, if this alters the value of get_status
template<typename MemoryProvider>
Action dealloc_short_slab(MemoryProvider& memory_provider)
Action dealloc_short_slab()
{
// This is the short slab.
if constexpr (decommit_strategy == DecommitAll)
{
memory_provider.notify_not_using(
pointer_offset(this, OS_PAGE_SIZE), SLAB_SIZE - OS_PAGE_SIZE);
}
bool was_full = is_full();
used--;