Skip to content

Commit 19de27f

Browse files
committed
Improve fast path of handle remote deallocs
This adds some branch predictor and cache hints to the fast path of processing remote deallocation. It also removes the batching.
1 parent fd40863 commit 19de27f

File tree

4 files changed

+15
-20
lines changed

4 files changed

+15
-20
lines changed

src/mem/allocconfig.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,6 @@ namespace snmalloc
2424
1 << 20
2525
#endif
2626
;
27-
28-
// Handle at most this many object from the remote dealloc queue at a time.
29-
static constexpr size_t REMOTE_BATCH =
30-
#ifdef USE_REMOTE_BATCH
31-
REMOTE_BATCH
32-
#else
33-
4096
34-
#endif
35-
;
36-
3727
enum DecommitStrategy
3828
{
3929
/**

src/mem/corealloc.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -457,8 +457,7 @@ namespace snmalloc
457457
[local_state](freelist::QueuePtr p) SNMALLOC_FAST_PATH_LAMBDA {
458458
return capptr_domesticate<SharedStateHandle>(local_state, p);
459459
};
460-
size_t i = 0;
461-
auto cb = [this, local_state, &need_post, &i](freelist::HeadPtr msg)
460+
auto cb = [this, local_state, &need_post](freelist::HeadPtr msg)
462461
SNMALLOC_FAST_PATH_LAMBDA {
463462
#ifdef SNMALLOC_TRACING
464463
std::cout << "Handling remote" << std::endl;
@@ -469,7 +468,7 @@ namespace snmalloc
469468

470469
handle_dealloc_remote(entry, msg.as_void(), need_post);
471470

472-
return (i++ < REMOTE_BATCH);
471+
return true;
473472
};
474473

475474
if constexpr (SharedStateHandle::Options.QueueHeadsAreTame)

src/mem/remoteallocator.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,21 @@ namespace snmalloc
146146
Cb cb)
147147
{
148148
invariant();
149+
150+
// Use back to bound, so we don't handle new entries.
151+
auto b = back.load(std::memory_order_relaxed);
149152
freelist::HeadPtr curr = domesticate_head(front);
150-
freelist::HeadPtr next = curr->atomic_read_next(key, domesticate_queue);
151153

152-
while (next != nullptr)
154+
while (address_cast(curr) != address_cast(b))
153155
{
154-
if (!cb(curr))
156+
freelist::HeadPtr next = curr->atomic_read_next(key, domesticate_queue);
157+
// We have observed a non-linearisable effect of the queue.
158+
// Just go back to allocating normally.
159+
if (unlikely(next == nullptr))
160+
break;
161+
// We want this element next, so start it loading.
162+
Aal::prefetch(next.unsafe_ptr());
163+
if (unlikely(!cb(curr)))
155164
{
156165
/*
157166
* We've domesticate_queue-d next so that we can read through it, but
@@ -168,7 +177,6 @@ namespace snmalloc
168177
}
169178

170179
curr = next;
171-
next = next->atomic_read_next(key, domesticate_queue);
172180
}
173181

174182
/*

src/test/func/domestication/domestication.cc

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,14 +154,12 @@ int main()
154154
*
155155
* - RemoteAllocator::dequeue domesticating the stub's next pointer (p)
156156
*
157-
* - RemoteAllocator::dequeue domesticating nullptr (p is the last message)
158-
*
159157
* - Metaslab::alloc_free_list, domesticating the successor object in the
160158
* newly minted freelist::Iter (i.e., the thing that would be allocated
161159
* after q).
162160
*/
163161
static constexpr size_t expected_count =
164-
snmalloc::CustomGlobals::Options.QueueHeadsAreTame ? 3 : 4;
162+
snmalloc::CustomGlobals::Options.QueueHeadsAreTame ? 2 : 3;
165163
SNMALLOC_CHECK(snmalloc::CustomGlobals::domesticate_count == expected_count);
166164

167165
// Prevent the allocators from going out of scope during the above test

0 commit comments

Comments
 (0)