diff options
| author | 2024-01-30 20:14:06 +0100 | |
|---|---|---|
| committer | 2024-01-31 16:38:51 +0100 | |
| commit | 738e9a79a06c9d3955488022a1d3afd67bc5a11d (patch) | |
| tree | f9d574ddd4e886e1e7938db8d5f6e68bed5eb240 /src | |
| parent | NVDRV: Join the heaper optimization blocks (diff) | |
| download | yuzu-738e9a79a06c9d3955488022a1d3afd67bc5a11d.tar.gz yuzu-738e9a79a06c9d3955488022a1d3afd67bc5a11d.tar.xz yuzu-738e9a79a06c9d3955488022a1d3afd67bc5a11d.zip | |
DeviceMemory: Make counter types configurable
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/device_memory_manager.h | 15 | ||||
| -rw-r--r-- | src/core/device_memory_manager.inc | 18 |
2 files changed, 19 insertions, 14 deletions
diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h index 63823602c..0568a821b 100644 --- a/src/core/device_memory_manager.h +++ b/src/core/device_memory_manager.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <atomic> | 7 | #include <atomic> |
| 8 | #include <bit> | ||
| 8 | #include <deque> | 9 | #include <deque> |
| 9 | #include <memory> | 10 | #include <memory> |
| 10 | #include <mutex> | 11 | #include <mutex> |
| @@ -181,24 +182,28 @@ private: | |||
| 181 | } | 182 | } |
| 182 | 183 | ||
| 183 | Common::VirtualBuffer<VAddr> cpu_backing_address; | 184 | Common::VirtualBuffer<VAddr> cpu_backing_address; |
| 184 | static constexpr size_t subentries = 8 / sizeof(u8); | 185 | using CounterType = u8; |
| 186 | using CounterAtomicType = std::atomic_uint8_t; | ||
| 187 | static constexpr size_t subentries = 8 / sizeof(CounterType); | ||
| 185 | static constexpr size_t subentries_mask = subentries - 1; | 188 | static constexpr size_t subentries_mask = subentries - 1; |
| 189 | static constexpr size_t subentries_shift = | ||
| 190 | std::countr_zero(sizeof(u64)) - std::countr_zero(sizeof(CounterType)); | ||
| 186 | class CounterEntry final { | 191 | class CounterEntry final { |
| 187 | public: | 192 | public: |
| 188 | CounterEntry() = default; | 193 | CounterEntry() = default; |
| 189 | 194 | ||
| 190 | std::atomic_uint8_t& Count(std::size_t page) { | 195 | CounterAtomicType& Count(std::size_t page) { |
| 191 | return values[page & subentries_mask]; | 196 | return values[page & subentries_mask]; |
| 192 | } | 197 | } |
| 193 | 198 | ||
| 194 | const std::atomic_uint8_t& Count(std::size_t page) const { | 199 | const CounterAtomicType& Count(std::size_t page) const { |
| 195 | return values[page & subentries_mask]; | 200 | return values[page & subentries_mask]; |
| 196 | } | 201 | } |
| 197 | 202 | ||
| 198 | private: | 203 | private: |
| 199 | std::array<std::atomic_uint8_t, subentries> values{}; | 204 | std::array<CounterAtomicType, subentries> values{}; |
| 200 | }; | 205 | }; |
| 201 | static_assert(sizeof(CounterEntry) == subentries * sizeof(u8), | 206 | static_assert(sizeof(CounterEntry) == subentries * sizeof(CounterType), |
| 202 | "CounterEntry should be 8 bytes!"); | 207 | "CounterEntry should be 8 bytes!"); |
| 203 | 208 | ||
| 204 | static constexpr size_t num_counter_entries = | 209 | static constexpr size_t num_counter_entries = |
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 0a59000aa..7afe54949 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc | |||
| @@ -213,8 +213,8 @@ void DeviceMemoryManager<Traits>::Free(DAddr start, size_t size) { | |||
| 213 | } | 213 | } |
| 214 | 214 | ||
| 215 | template <typename Traits> | 215 | template <typename Traits> |
| 216 | void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, | 216 | void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, Asid asid, |
| 217 | Asid asid, bool track) { | 217 | bool track) { |
| 218 | Core::Memory::Memory* process_memory = registered_processes[asid.id]; | 218 | Core::Memory::Memory* process_memory = registered_processes[asid.id]; |
| 219 | size_t start_page_d = address >> Memory::YUZU_PAGEBITS; | 219 | size_t start_page_d = address >> Memory::YUZU_PAGEBITS; |
| 220 | size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS; | 220 | size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS; |
| @@ -522,10 +522,10 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
| 522 | size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS; | 522 | size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS; |
| 523 | auto* memory_device_inter = registered_processes[asid.id]; | 523 | auto* memory_device_inter = registered_processes[asid.id]; |
| 524 | for (; page != page_end; ++page) { | 524 | for (; page != page_end; ++page) { |
| 525 | std::atomic_uint8_t& count = cached_pages->at(page >> 3).Count(page); | 525 | CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page); |
| 526 | 526 | ||
| 527 | if (delta > 0) { | 527 | if (delta > 0) { |
| 528 | ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<u8>::max(), | 528 | ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<CounterType>::max(), |
| 529 | "Count may overflow!"); | 529 | "Count may overflow!"); |
| 530 | } else if (delta < 0) { | 530 | } else if (delta < 0) { |
| 531 | ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); | 531 | ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); |
| @@ -534,7 +534,7 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
| 534 | } | 534 | } |
| 535 | 535 | ||
| 536 | // Adds or subtracts 1, as count is a unsigned 8-bit value | 536 | // Adds or subtracts 1, as count is a unsigned 8-bit value |
| 537 | count.fetch_add(static_cast<u8>(delta), std::memory_order_release); | 537 | count.fetch_add(static_cast<CounterType>(delta), std::memory_order_release); |
| 538 | 538 | ||
| 539 | // Assume delta is either -1 or 1 | 539 | // Assume delta is either -1 or 1 |
| 540 | if (count.load(std::memory_order::relaxed) == 0) { | 540 | if (count.load(std::memory_order::relaxed) == 0) { |
| @@ -553,15 +553,15 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
| 553 | } | 553 | } |
| 554 | cache_bytes += Memory::YUZU_PAGESIZE; | 554 | cache_bytes += Memory::YUZU_PAGESIZE; |
| 555 | } else if (cache_bytes > 0) { | 555 | } else if (cache_bytes > 0) { |
| 556 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, | 556 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, |
| 557 | true); | 557 | cache_bytes, true); |
| 558 | cache_bytes = 0; | 558 | cache_bytes = 0; |
| 559 | } | 559 | } |
| 560 | vpage++; | 560 | vpage++; |
| 561 | } | 561 | } |
| 562 | if (uncache_bytes > 0) { | 562 | if (uncache_bytes > 0) { |
| 563 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes, | 563 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, |
| 564 | false); | 564 | uncache_bytes, false); |
| 565 | } | 565 | } |
| 566 | if (cache_bytes > 0) { | 566 | if (cache_bytes > 0) { |
| 567 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, | 567 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, |