This is an archive of the discontinued LLVM Phabricator instance.

[Orc][JITLink] Slab based memory allocator to reduce RPC calls
ClosedPublic

Authored by argentite on Jul 22 2022, 12:37 PM.

Details

Summary

Calling reserve() used to require an RPC call. This commit allows large
ranges of executor address space to be reserved. Subsequent calls to
reserve() will return subranges of already reserved address space while
there is still space available.

Diff Detail

Event Timeline

argentite created this revision.Jul 22 2022, 12:37 PM
Herald added a project: Restricted Project. · View Herald TranscriptJul 22 2022, 12:37 PM
lhames added inline comments.Jul 25 2022, 2:36 PM
llvm/lib/ExecutionEngine/Orc/MapperJITLinkMemoryManager.cpp
62

It looks like the algorithm here is:

  1. lock
  2. search for range
  3. unlock
  4. check if range found
  5. if so then CompleteAllocation, otherwise reserve and CompleteAllocation in the callback.

The problem is that if we start off with two concurrent allocate calls we might allocate two different slabs, which we don't want to do. I think the allocator should do a blocking call to reserve under the lock instead. That'll hit the first caller hard, but it guarantees that we don't allocate more than one slab until/unless the first one fills up.

(We could also make this configurable too -- we want the slab allocator to be able to guarantee memory range constraints to enable use of arbitrary small code model code, but it's also useful as a performance optimization, so two arguments "slab size" and "allow concurrent reservations" would make sense. I think that should be a follow-up patch though).

argentite marked an inline comment as done.

When enough memory is not already reserved, lock the mutex while doing the RPC to prevent subsequent allocations to request new memory ranges

argentite updated this revision to Diff 448300.Jul 28 2022, 4:31 AM
argentite retitled this revision from [Orc][JITLink] Custom memory allocator to reduce RPC calls to [Orc][JITLink] Slab based memory allocator to reduce RPC calls.
argentite edited the summary of this revision. (Show Details)

Updated title and commit message

argentite published this revision for review.Jul 28 2022, 4:34 AM
Herald added a project: Restricted Project. · View Herald TranscriptJul 28 2022, 4:34 AM
lhames accepted this revision.Aug 3 2022, 12:25 PM

LGTM!

llvm/include/llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h
55–58

// Ranges that have been reserved on both side
DenseMap<ExecutorAddr, ExecutorAddrDiff> UsedMemory;

I didn't understand this comment? This is just the used memory list, right? Whether or not there's any memory associated with it on the controller side should be up to the mapper, rather than the allocator.

llvm/lib/ExecutionEngine/Orc/MapperJITLinkMemoryManager.cpp
72–87

I think this check should probably be dropped: We support JITing on a 32-bit controller for a 64-bit target, so you could request, e.g., an 8Gb zero-fill data section. That would overflow a size_t on the controller, but is still perfectly legal.

On the other hand if you overflow the address scape for the executor then you'll definitely overflow the available space too, so you'll error out below anyway.

157

There's no coalescing of the AvailableMemory list yet, so you'll get fragmentation in the allocator. I think that should be addressed in a follow-up patch though.

This revision is now accepted and ready to land.Aug 3 2022, 12:25 PM
argentite updated this revision to Diff 450616.Aug 7 2022, 5:12 AM
argentite marked 2 inline comments as done.

Remove address space size check and improve comments

argentite added inline comments.Aug 7 2022, 5:19 AM
llvm/include/llvm/ExecutionEngine/Orc/MapperJITLinkMemoryManager.h
55–58

I have tried to make the language clearer.

llvm/lib/ExecutionEngine/Orc/MapperJITLinkMemoryManager.cpp
157

I plan to do a more efficient implementation as a follow up.