Browse Source

[large_vector] zero regions more efficiently

pull/4219/head
Exverge 2 weeks ago
parent
commit
a398baae06
No known key found for this signature in database GPG Key ID: DAD399BCC5FB77E4
  1. 34
      src/common/sparse_large_vector.h
  2. 6
      src/core/memory.cpp

34
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. /// Returns a reference to the value of the requested index and allocates memory if needed.
T& GetAndFault(std::size_t index) noexcept { T& GetAndFault(std::size_t index) noexcept {
if (index > alloc_size / sizeof(T)) { if (index > alloc_size / sizeof(T)) {
@ -114,13 +106,29 @@ public:
base_ptr[index] = value; 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<u64>(start) * sizeof(T);
const u64 end = static_cast<u64>(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<void*>(base), 0, first_size);
}
if (end <= end_page)
return; return;
base = end_page;
for (u64 page = base; page < end; page += HostPageSize) {
if (!IsCommittedPage(page / sizeof(T))) {
continue;
}
std::memset(reinterpret_cast<void*>(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<void*>(&base_ptr[index]), 0, sizeof(T));
} }
constexpr void CommitRegion(size_t index, size_t end_) { constexpr void CommitRegion(size_t index, size_t end_) {

6
src/core/memory.cpp

@ -548,11 +548,7 @@ struct Memory::Impl {
ASSERT_MSG(type != Common::PageType::Memory, ASSERT_MSG(type != Common::PageType::Memory,
"Mapping memory page without a pointer @ {:016x}", base * YUZU_PAGESIZE); "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 { } else {
auto orig_base = base; auto orig_base = base;

Loading…
Cancel
Save