Skip to content

Commit 7944d8f

Browse files
committed
WIP: Hack to optimise based on known sizes
If the caller knows the sizes, and knows the allocation is thread local, then we can make some significant optimisations. This is a brief hack to show where would need changing.
1 parent db3580a commit 7944d8f

File tree

5 files changed

+57
-3
lines changed

5 files changed

+57
-3
lines changed

src/mem/alloc.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1040,7 +1040,8 @@ namespace snmalloc
10401040
allow_reserve == NoReserve ? "noreserve" : "reserve"));
10411041

10421042
SNMALLOC_ASSUME(size <= SLAB_SIZE);
1043-
sizeclass_t sizeclass = size_to_sizeclass(size);
1043+
SNMALLOC_ASSUME(size > 0);
1044+
sizeclass_t sizeclass = size_to_sizeclass<true>(size);
10441045
return small_alloc_inner<zero_mem, allow_reserve>(sizeclass, size);
10451046
}
10461047

@@ -1066,6 +1067,13 @@ namespace snmalloc
10661067
return p;
10671068
}
10681069

1070+
return small_alloc_inner_slow<zero_mem, allow_reserve>(sizeclass, size);
1071+
}
1072+
1073+
template<ZeroMem zero_mem, AllowReserve allow_reserve>
1074+
SNMALLOC_FAST_PATH void*
1075+
small_alloc_inner_slow(sizeclass_t sizeclass, size_t size)
1076+
{
10691077
if (likely(!has_messages()))
10701078
return small_alloc_next_free_list<zero_mem, allow_reserve>(
10711079
sizeclass, size);
@@ -1228,6 +1236,21 @@ namespace snmalloc
12281236
small_dealloc_offseted_inner(super, p, sizeclass);
12291237
}
12301238

1239+
static SNMALLOC_FAST_PATH bool small_local_dealloc(void* p)
1240+
{
1241+
auto super = Superslab::get(p);
1242+
Slab* slab = Metaslab::get_slab(p);
1243+
return (likely(slab->dealloc_fast(super, p)));
1244+
}
1245+
1246+
SNMALLOC_FAST_PATH void small_local_dealloc_slow(void* p)
1247+
{
1248+
auto super = Superslab::get(p);
1249+
Slab* slab = Metaslab::get_slab(p);
1250+
small_dealloc_offseted_slow(super, p, slab->get_meta().sizeclass);
1251+
}
1252+
1253+
12311254
SNMALLOC_FAST_PATH void small_dealloc_offseted_inner(
12321255
Superslab* super, void* p, sizeclass_t sizeclass)
12331256
{

src/mem/sizeclass.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace snmalloc
2020
constexpr static size_t
2121
sizeclass_to_inverse_cache_friendly_mask(sizeclass_t sc);
2222
constexpr static uint16_t medium_slab_free(sizeclass_t sizeclass);
23-
static sizeclass_t size_to_sizeclass(size_t size);
23+
template<bool ASSUME_SMALL = false> static sizeclass_t size_to_sizeclass(size_t size);
2424

2525
constexpr static inline sizeclass_t size_to_sizeclass_const(size_t size)
2626
{

src/mem/sizeclasstable.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,10 @@ namespace snmalloc
110110
return sizeclass_metadata.inverse_cache_friendly_mask[sizeclass];
111111
}
112112

113+
template <bool ASSUME_SMALL>
113114
static inline sizeclass_t size_to_sizeclass(size_t size)
114115
{
115-
if ((size - 1) <= (SLAB_SIZE - 1))
116+
if ((size - 1) <= (SLAB_SIZE - 1) || ASSUME_SMALL)
116117
{
117118
auto index = sizeclass_lookup_index(size);
118119
SNMALLOC_ASSUME(index <= sizeclass_lookup_index(SLAB_SIZE));

src/override/malloc.cc

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,25 @@ extern "C"
6969
return ThreadAlloc::get_noncachable()->alloc<ZeroMem::YesZero>(sz);
7070
}
7171

72+
SNMALLOC_EXPORT
73+
void SNMALLOC_NAME_MANGLE(free_local_small)(void* ptr)
74+
{
75+
if (Alloc::small_local_dealloc(ptr)) return;
76+
ThreadAlloc::get_noncachable()->small_local_dealloc_slow(ptr);
77+
}
78+
79+
SNMALLOC_EXPORT
80+
void* SNMALLOC_NAME_MANGLE(malloc_small)(size_t size)
81+
{
82+
return ThreadAlloc::get_noncachable()->small_alloc<NoZero, YesReserve>(size);
83+
}
84+
85+
SNMALLOC_EXPORT
86+
void* SNMALLOC_NAME_MANGLE(malloc_small_64)()
87+
{
88+
return ThreadAlloc::get_noncachable()->small_alloc<NoZero, YesReserve>(64);
89+
}
90+
7291
SNMALLOC_EXPORT
7392
size_t SNMALLOC_NAME_MANGLE(malloc_usable_size)(
7493
MALLOC_USABLE_SIZE_QUALIFIER void* ptr)

src/test/func/malloc/malloc.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,12 @@ void test_memalign(size_t size, size_t align, int err, bool null)
116116
check_result(size, align, p, err, null);
117117
}
118118

119+
void test_local(size_t size)
120+
{
121+
for (int n = 0; n < 1000; n++)
122+
our_free_local_small(our_malloc_small(size));
123+
}
124+
119125
int main(int argc, char** argv)
120126
{
121127
UNUSED(argc);
@@ -125,6 +131,11 @@ int main(int argc, char** argv)
125131

126132
constexpr int SUCCESS = 0;
127133

134+
for (size_t i = 1; i < SLAB_SIZE; i+=16)
135+
{
136+
test_local(i);
137+
}
138+
128139
test_realloc(our_malloc(64), 4194304, SUCCESS, false);
129140

130141
for (sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++)

0 commit comments

Comments
 (0)