From a398baae062052ff0951db97ab296a18b4dde507 Mon Sep 17 00:00:00 2001 From: Exverge Date: Wed, 29 Jul 2026 22:25:04 -0400 Subject: [PATCH] [large_vector] zero regions more efficiently --- src/common/sparse_large_vector.h | 34 ++++++++++++++++++++------------ src/core/memory.cpp | 6 +----- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/common/sparse_large_vector.h b/src/common/sparse_large_vector.h index 8e6639e16a..d360076de0 100644 --- a/src/common/sparse_large_vector.h +++ b/src/common/sparse_large_vector.h @@ -73,14 +73,6 @@ public: } } - /// Returns a pointer to the value of the requested index if that page has been allocated, or otherwise return nullptr. - T* GetNoFault(std::size_t index) const noexcept { - if (!IsCommittedPage(index)) { - return nullptr; - } - return &base_ptr[index]; - } - /// Returns a reference to the value of the requested index and allocates memory if needed. T& GetAndFault(std::size_t index) noexcept { if (index > alloc_size / sizeof(T)) { @@ -114,13 +106,29 @@ public: base_ptr[index] = value; } - void Zero(std::size_t index) noexcept { - if (!IsCommittedPage(index)) { + void ZeroRegion(std::size_t start, std::size_t end_) noexcept { + u64 base = static_cast(start) * sizeof(T); + const u64 end = static_cast(end_) * sizeof(T); + + const u64 end_page = AlignUp(base, HostPageSize); + const u64 first_size = std::min(end_page, end) - base; + + if (IsCommittedPage(base / sizeof(T))) { + std::memset(reinterpret_cast(base), 0, first_size); + } + + if (end <= end_page) return; + + base = end_page; + + for (u64 page = base; page < end; page += HostPageSize) { + if (!IsCommittedPage(page / sizeof(T))) { + continue; + } + + std::memset(reinterpret_cast(page), 0, std::min( HostPageSize, end - page)); } - // reinterpret_cast because C++ doesn't like memset'ing, but this should be valid - // because of std::is_trivially_copyable_v - std::memset(reinterpret_cast(&base_ptr[index]), 0, sizeof(T)); } constexpr void CommitRegion(size_t index, size_t end_) { diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 9b4e0d878b..a14ca07a7e 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -548,11 +548,7 @@ struct Memory::Impl { ASSERT_MSG(type != Common::PageType::Memory, "Mapping memory page without a pointer @ {:016x}", base * YUZU_PAGESIZE); - while (base != end) { - // TODO: add a ZeroRegion function - page_table.entries.Zero(base); - base += 1; - } + page_table.entries.ZeroRegion(base, end); } else { auto orig_base = base;