From ac84ea17a6248062e556065f56a2ae564ff5a303 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 21 Jun 2025 20:00:39 +0200 Subject: [PATCH] Memmap: Optimize UpdateLogicalMemory by merging mappings Instead of creating many 128 KiB mappings, we can create a few large mappings. On my Windows PC, this speeds up GameCube (FakeVMEM) game boot times by about 200 ms and Wii game boot times by about 60 ms. Loading savestates is also faster, by about 45 ms for GameCube (FakeVMEM) games and 5 ms for Wii games. The impact is presumably smaller on other OSes because Windows is particularly slow at creating mappings. --- Source/Core/Core/HW/Memmap.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/HW/Memmap.cpp b/Source/Core/Core/HW/Memmap.cpp index be58fbfc69..675e942009 100644 --- a/Source/Core/Core/HW/Memmap.cpp +++ b/Source/Core/Core/HW/Memmap.cpp @@ -248,9 +248,24 @@ void MemoryManager::UpdateLogicalMemory(const PowerPC::BatTable& dbat_table) if (dbat_table[i] & PowerPC::BAT_PHYSICAL_BIT) { u32 logical_address = i << PowerPC::BAT_INDEX_SHIFT; - // TODO: Merge adjacent mappings to make this faster. u32 logical_size = PowerPC::BAT_PAGE_SIZE; u32 translated_address = dbat_table[i] & PowerPC::BAT_RESULT_MASK; + + while (i + 1 < dbat_table.size()) + { + if (!(dbat_table[i + 1] & PowerPC::BAT_PHYSICAL_BIT)) + { + ++i; + break; + } + + if ((dbat_table[i + 1] & PowerPC::BAT_RESULT_MASK) != translated_address + logical_size) + break; + + ++i; + logical_size += PowerPC::BAT_PAGE_SIZE; + } + for (const auto& physical_region : m_physical_regions) { if (!physical_region.active)