From 844e43b0438f0d79af0deb247330504151e035cd Mon Sep 17 00:00:00 2001 From: CamilleLaVey Date: Thu, 15 Jan 2026 06:04:06 +0100 Subject: [PATCH] [TEST] Instrumentalization for WordManager - DeviceMemoryManager --- src/core/device_memory_manager.h | 25 +++++++++++++++++++++ src/core/device_memory_manager.inc | 29 ++++++++++++++++++++++++- src/tests/video_core/memory_tracker.cpp | 18 +++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h index 6dcf7bb228..5391229191 100644 --- a/src/core/device_memory_manager.h +++ b/src/core/device_memory_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -117,6 +120,20 @@ public: void UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta); +#if defined(YUZU_TESTS) + // Instrumentation getters for testing + [[nodiscard]] size_t UpdatePagesCachedCalls() const noexcept { return update_pages_cached_calls.load(std::memory_order_relaxed); } + [[nodiscard]] uint64_t UpdatePagesCachedTotalNs() const noexcept { return update_pages_cached_total_ns.load(std::memory_order_relaxed); } + [[nodiscard]] uint64_t UpdatePagesCachedMaxNs() const noexcept { return update_pages_cached_max_ns.load(std::memory_order_relaxed); } + [[nodiscard]] size_t UpdatePagesCachedTotalBytes() const noexcept { return update_pages_cached_total_bytes.load(std::memory_order_relaxed); } + void ResetUpdatePagesCachedMetrics() noexcept { + update_pages_cached_calls.store(0, std::memory_order_relaxed); + update_pages_cached_total_ns.store(0, std::memory_order_relaxed); + update_pages_cached_max_ns.store(0, std::memory_order_relaxed); + update_pages_cached_total_bytes.store(0, std::memory_order_relaxed); + } +#endif + static constexpr size_t AS_BITS = Traits::device_virtual_bits; private: @@ -214,6 +231,14 @@ private: std::unique_ptr cached_pages; Common::RangeMutex counter_guard; std::mutex mapping_guard; + +#if defined(YUZU_TESTS) + // Instrumentation counters for UpdatePagesCachedCount + mutable std::atomic_size_t update_pages_cached_calls{0}; + mutable std::atomic update_pages_cached_total_ns{0}; + mutable std::atomic update_pages_cached_max_ns{0}; + mutable std::atomic_size_t update_pages_cached_total_bytes{0}; +#endif }; } // namespace Core diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 52dff5df9a..00c400849a 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -163,6 +166,14 @@ template DeviceMemoryManager::DeviceMemoryManager(const DeviceMemory& device_memory_) : physical_base{reinterpret_cast(device_memory_.buffer.BackingBasePointer())}, device_inter{nullptr}, compressed_physical_ptr(device_as_size >> Memory::YUZU_PAGEBITS), +#if defined(YUZU_TESTS) + update_pages_cached_calls{0}, update_pages_cached_total_ns{0}, update_pages_cached_max_ns{0}, update_pages_cached_total_bytes{0}, +#endif + compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == + Settings::MemoryLayout::Memory_4Gb + ? physical_min_bits + : physical_max_bits) - + Memory::YUZU_PAGEBITS)), compressed_device_addr(1ULL << ((Settings::values.memory_layout_mode.GetValue() == Settings::MemoryLayout::Memory_4Gb ? physical_min_bits @@ -484,7 +495,7 @@ void DeviceMemoryManager::WriteBlockUnsafe(DAddr address, const void* sr [&](const std::size_t copy_amount) { src_pointer = static_cast(src_pointer) + copy_amount; }); -} +}#include template Asid DeviceMemoryManager::RegisterProcess(Memory::Memory* memory_device_inter) { @@ -508,6 +519,9 @@ void DeviceMemoryManager::UnregisterProcess(Asid asid) { template void DeviceMemoryManager::UpdatePagesCachedCount(DAddr addr, size_t size, s32 delta) { +#if defined(YUZU_TESTS) + const auto start_time = std::chrono::steady_clock::now(); +#endif Common::ScopedRangeLock lk(counter_guard, addr, size); u64 uncache_begin = 0; u64 cache_begin = 0; @@ -584,6 +598,19 @@ void DeviceMemoryManager::UpdatePagesCachedCount(DAddr addr, size_t size } } release_pending(); + +#if defined(YUZU_TESTS) + const auto end_time = std::chrono::steady_clock::now(); + const uint64_t ns = std::chrono::duration_cast(end_time - start_time).count(); + update_pages_cached_calls.fetch_add(1, std::memory_order_relaxed); + update_pages_cached_total_ns.fetch_add(ns, std::memory_order_relaxed); + update_pages_cached_total_bytes.fetch_add(size, std::memory_order_relaxed); + // Update max + uint64_t old_max = update_pages_cached_max_ns.load(std::memory_order_relaxed); + while (old_max < ns && !update_pages_cached_max_ns.compare_exchange_weak(old_max, ns, std::memory_order_relaxed)) { + // loop until updated + } +#endif } } // namespace Core diff --git a/src/tests/video_core/memory_tracker.cpp b/src/tests/video_core/memory_tracker.cpp index 5bf40876e3..ddcdf0ce08 100644 --- a/src/tests/video_core/memory_tracker.cpp +++ b/src/tests/video_core/memory_tracker.cpp @@ -11,6 +11,8 @@ #include "common/common_types.h" #include "video_core/buffer_cache/memory_tracker_base.h" +#include "core/device_memory.h" +#include "video_core/host1x/gpu_device_memory_manager.h" namespace { using Range = std::pair; @@ -571,3 +573,19 @@ TEST_CASE("MemoryTracker: FlushCachedWrites batching") { REQUIRE(std::get<0>(calls[1]) == c + PAGE * 4); REQUIRE(std::get<1>(calls[1]) == PAGE); } + +TEST_CASE("DeviceMemoryManager: UpdatePagesCachedCount instrumentation") { + Core::DeviceMemory device_memory; + Tegra::MaxwellDeviceMemoryManager manager(device_memory); +#if defined(YUZU_TESTS) + manager.ResetUpdatePagesCachedMetrics(); + REQUIRE(manager.UpdatePagesCachedCalls() == 0); + manager.UpdatePagesCachedCount(0, Core::Memory::YUZU_PAGESIZE, 1); + REQUIRE(manager.UpdatePagesCachedCalls() == 1); + REQUIRE(manager.UpdatePagesCachedTotalBytes() >= Core::Memory::YUZU_PAGESIZE); + REQUIRE(manager.UpdatePagesCachedTotalNs() > 0); + REQUIRE(manager.UpdatePagesCachedMaxNs() > 0); +#else + SUCCEED("Instrumentation only available in test builds"); +#endif +}