From 425ccf333b61bded68a439637e87a619b21a012c Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 8 Aug 2025 18:47:03 +0100 Subject: [PATCH] [dynarmic] reduce exclusive monitor overhead Signed-off-by: lizzie --- src/core/hardware_properties.h | 2 +- .../src/dynarmic/backend/arm64/exclusive_monitor.cpp | 2 +- .../src/dynarmic/backend/x64/exclusive_monitor.cpp | 12 ++++-------- src/dynarmic/src/dynarmic/common/spin_lock.h | 5 ++--- src/dynarmic/src/dynarmic/common/spin_lock_arm64.cpp | 4 ++-- src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp | 4 ++-- .../src/dynarmic/interface/exclusive_monitor.h | 8 ++++---- 7 files changed, 16 insertions(+), 21 deletions(-) diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h index 191c28bb46..3f870becbf 100644 --- a/src/core/hardware_properties.h +++ b/src/core/hardware_properties.h @@ -15,7 +15,7 @@ namespace Hardware { constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz -constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores +constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores - sync with dynarmic exclusive_monitor.h // Virtual to Physical core map. constexpr std::array()> VirtualToPhysicalCoreMap{ diff --git a/src/dynarmic/src/dynarmic/backend/arm64/exclusive_monitor.cpp b/src/dynarmic/src/dynarmic/backend/arm64/exclusive_monitor.cpp index 326ab4ad00..b47167bf6f 100644 --- a/src/dynarmic/src/dynarmic/backend/arm64/exclusive_monitor.cpp +++ b/src/dynarmic/src/dynarmic/backend/arm64/exclusive_monitor.cpp @@ -14,7 +14,7 @@ namespace Dynarmic { -ExclusiveMonitor::ExclusiveMonitor(size_t processor_count) +ExclusiveMonitor::ExclusiveMonitor(std::size_t processor_count) : exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {} size_t ExclusiveMonitor::GetProcessorCount() const { diff --git a/src/dynarmic/src/dynarmic/backend/x64/exclusive_monitor.cpp b/src/dynarmic/src/dynarmic/backend/x64/exclusive_monitor.cpp index 09ef60205f..f8237c99e8 100644 --- a/src/dynarmic/src/dynarmic/backend/x64/exclusive_monitor.cpp +++ b/src/dynarmic/src/dynarmic/backend/x64/exclusive_monitor.cpp @@ -14,7 +14,7 @@ namespace Dynarmic { -ExclusiveMonitor::ExclusiveMonitor(size_t processor_count) +ExclusiveMonitor::ExclusiveMonitor(std::size_t processor_count) : exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {} size_t ExclusiveMonitor::GetProcessorCount() const { @@ -29,20 +29,16 @@ void ExclusiveMonitor::Unlock() { lock.Unlock(); } -bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) { +bool ExclusiveMonitor::CheckAndClear(std::size_t processor_id, VAddr address) { const VAddr masked_address = address & RESERVATION_GRANULE_MASK; - Lock(); if (exclusive_addresses[processor_id] != masked_address) { Unlock(); return false; } - - for (VAddr& other_address : exclusive_addresses) { - if (other_address == masked_address) { + for (VAddr& other_address : exclusive_addresses) + if (other_address == masked_address) other_address = INVALID_EXCLUSIVE_ADDRESS; - } - } return true; } diff --git a/src/dynarmic/src/dynarmic/common/spin_lock.h b/src/dynarmic/src/dynarmic/common/spin_lock.h index f653704db6..e97ba2897f 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock.h +++ b/src/dynarmic/src/dynarmic/common/spin_lock.h @@ -8,9 +8,8 @@ namespace Dynarmic { struct SpinLock { - void Lock(); - void Unlock(); - + void Lock() noexcept; + void Unlock() noexcept; volatile int storage = 0; }; diff --git a/src/dynarmic/src/dynarmic/common/spin_lock_arm64.cpp b/src/dynarmic/src/dynarmic/common/spin_lock_arm64.cpp index ccf807e2d2..7833b65403 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock_arm64.cpp +++ b/src/dynarmic/src/dynarmic/common/spin_lock_arm64.cpp @@ -73,12 +73,12 @@ void SpinLockImpl::Initialize() { } // namespace -void SpinLock::Lock() { +void SpinLock::Lock() noexcept { std::call_once(flag, &SpinLockImpl::Initialize, impl); impl.lock(&storage); } -void SpinLock::Unlock() { +void SpinLock::Unlock() noexcept { std::call_once(flag, &SpinLockImpl::Initialize, impl); impl.unlock(&storage); } diff --git a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp index f0e44dc62e..474c2f8404 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp +++ b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp @@ -62,12 +62,12 @@ void SpinLockImpl::Initialize() { } // namespace -void SpinLock::Lock() { +void SpinLock::Lock() noexcept { std::call_once(flag, &SpinLockImpl::Initialize, impl); impl.lock(&storage); } -void SpinLock::Unlock() { +void SpinLock::Unlock() noexcept { std::call_once(flag, &SpinLockImpl::Initialize, impl); impl.unlock(&storage); } diff --git a/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h b/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h index 4813675873..566743c767 100644 --- a/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h +++ b/src/dynarmic/src/dynarmic/interface/exclusive_monitor.h @@ -6,11 +6,10 @@ #pragma once #include -#include #include #include #include -#include +#include #include @@ -80,9 +79,10 @@ private: static constexpr VAddr RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFFFull; static constexpr VAddr INVALID_EXCLUSIVE_ADDRESS = 0xDEAD'DEAD'DEAD'DEADull; + static constexpr size_t MAX_NUM_CPU_CORES = 4; // Sync with src/core/hardware_properties + boost::container::static_vector exclusive_addresses; + boost::container::static_vector exclusive_values; SpinLock lock; - std::vector exclusive_addresses; - std::vector exclusive_values; }; } // namespace Dynarmic