Skip to content

Commit

Permalink
Merge pull request #2260 from Sonicadvance1/optimize_lookup_map
Browse files Browse the repository at this point in the history
LookupCache: Optimize cache clearing and allocation
  • Loading branch information
lioncash authored Dec 17, 2022
2 parents 6e733bf + cad0dc6 commit 2b6a020
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 10 deletions.
19 changes: 9 additions & 10 deletions External/FEXCore/Source/Interface/Core/LookupCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace FEXCore {
LookupCache::LookupCache(FEXCore::Context::Context *CTX)
: ctx {CTX} {

TotalCacheSize = ctx->Config.VirtualMemSize / 4096 * 8 + CODE_SIZE + L1_SIZE;

// Block cache ends up looking like this
// PageMemoryMap[VirtualMemoryRegion >> 12]
// |
Expand All @@ -29,27 +31,26 @@ LookupCache::LookupCache(FEXCore::Context::Context *CTX)
// Allocate a region of memory that we can use to back our block pointers
// We need one pointer per page of virtual memory
// At 64GB of virtual memory this will allocate 128MB of virtual memory space
PagePointer = reinterpret_cast<uintptr_t>(FEXCore::Allocator::mmap(nullptr, ctx->Config.VirtualMemSize / 4096 * 8, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
PagePointer = reinterpret_cast<uintptr_t>(FEXCore::Allocator::mmap(nullptr, TotalCacheSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));

// Allocate our memory backing our pages
// We need 32KB per guest page (One pointer per byte)
// XXX: We can drop down to 16KB if we store 4byte offsets from the code base
// We currently limit to 128MB of real memory for caching for the total cache size.
// Can end up being inefficient if we compile a small number of blocks per page
PageMemory = reinterpret_cast<uintptr_t>(FEXCore::Allocator::mmap(nullptr, CODE_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
PageMemory = PagePointer + ctx->Config.VirtualMemSize / 4096 * 8;
LOGMAN_THROW_AA_FMT(PageMemory != -1ULL, "Failed to allocate page memory");

// L1 Cache
L1Pointer = reinterpret_cast<uintptr_t>(FEXCore::Allocator::mmap(nullptr, L1_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0));
L1Pointer = PageMemory + CODE_SIZE;
LOGMAN_THROW_AA_FMT(L1Pointer != -1ULL, "Failed to allocate L1Pointer");

VirtualMemSize = ctx->Config.VirtualMemSize;
}

LookupCache::~LookupCache() {
FEXCore::Allocator::munmap(reinterpret_cast<void*>(PagePointer), ctx->Config.VirtualMemSize / 4096 * 8);
FEXCore::Allocator::munmap(reinterpret_cast<void*>(PageMemory), CODE_SIZE);
FEXCore::Allocator::munmap(reinterpret_cast<void*>(L1Pointer), L1_SIZE);
const size_t TotalCacheSize = ctx->Config.VirtualMemSize / 4096 * 8 + CODE_SIZE + L1_SIZE;
FEXCore::Allocator::munmap(reinterpret_cast<void*>(PagePointer), TotalCacheSize);
}

void LookupCache::ClearL2Cache() {
Expand All @@ -63,10 +64,8 @@ void LookupCache::ClearL2Cache() {
void LookupCache::ClearCache() {
std::lock_guard<std::recursive_mutex> lk(WriteLock);

// Clear L1
madvise(reinterpret_cast<void*>(L1Pointer), L1_SIZE, MADV_DONTNEED);
// Clear L2
ClearL2Cache();
// Clear L1 and L2 by clearing the full cache.
madvise(reinterpret_cast<void*>(PagePointer), TotalCacheSize, MADV_DONTNEED);
// All code is gone, remove links
BlockLinks.clear();
// All code is gone, clear the block list
Expand Down
2 changes: 2 additions & 0 deletions External/FEXCore/Source/Interface/Core/LookupCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,8 @@ class LookupCache {
std::map<BlockLinkTag, std::function<void()>> BlockLinks;
tsl::robin_map<uint64_t, uint64_t> BlockList;

size_t TotalCacheSize;

constexpr static size_t CODE_SIZE = 128 * 1024 * 1024;
constexpr static size_t SIZE_PER_PAGE = 4096 * sizeof(LookupCacheEntry);
constexpr static size_t L1_SIZE = L1_ENTRIES * sizeof(LookupCacheEntry);
Expand Down

0 comments on commit 2b6a020

Please sign in to comment.