diff options
author | liamwhite <liamwhite@users.noreply.github.com> | 2023-03-07 16:54:13 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-07 16:54:13 +0100 |
commit | a7792e5ff83523142230951ac7eacbd7685dc40b (patch) | |
tree | a7531c65e2ddec1122fc071d44c8106c48352ce3 /src/core | |
parent | Merge pull request #9890 from Kelebek1/reverb_fix (diff) | |
parent | native_clock: Round RDTSC frequency to the nearest 1000 (diff) | |
download | yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.gz yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.bz2 yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.lz yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.xz yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.tar.zst yuzu-a7792e5ff83523142230951ac7eacbd7685dc40b.zip |
Diffstat (limited to '')
-rw-r--r-- | src/core/core_timing.cpp | 55 | ||||
-rw-r--r-- | src/core/core_timing.h | 6 | ||||
-rw-r--r-- | src/core/hardware_properties.h | 8 |
3 files changed, 41 insertions, 28 deletions
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 3a63b52e3..742cfb996 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp @@ -6,6 +6,10 @@ #include <string> #include <tuple> +#ifdef _WIN32 +#include "common/windows/timer_resolution.h" +#endif + #include "common/microprofile.h" #include "core/core_timing.h" #include "core/core_timing_util.h" @@ -38,7 +42,8 @@ struct CoreTiming::Event { }; CoreTiming::CoreTiming() - : clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} + : cpu_clock{Common::CreateBestMatchingClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)}, + event_clock{Common::CreateStandardWallClock(Hardware::BASE_CLOCK_RATE, Hardware::CNTFREQ)} {} CoreTiming::~CoreTiming() { Reset(); @@ -185,15 +190,15 @@ void CoreTiming::ResetTicks() { } u64 CoreTiming::GetCPUTicks() const { - if (is_multicore) { - return clock->GetCPUCycles(); + if (is_multicore) [[likely]] { + return cpu_clock->GetCPUCycles(); } return ticks; } u64 CoreTiming::GetClockTicks() const { - if (is_multicore) { - return clock->GetClockCycles(); + if (is_multicore) [[likely]] { + return cpu_clock->GetClockCycles(); } return CpuCyclesToClockCycles(ticks); } @@ -252,21 +257,20 @@ void CoreTiming::ThreadLoop() { const auto next_time = Advance(); if (next_time) { // There are more events left in the queue, wait until the next event. - const auto wait_time = *next_time - GetGlobalTimeNs().count(); + auto wait_time = *next_time - GetGlobalTimeNs().count(); if (wait_time > 0) { #ifdef _WIN32 - // Assume a timer resolution of 1ms. - static constexpr s64 TimerResolutionNS = 1000000; + const auto timer_resolution_ns = + Common::Windows::GetCurrentTimerResolution().count(); - // Sleep in discrete intervals of the timer resolution, and spin the rest. - const auto sleep_time = wait_time - (wait_time % TimerResolutionNS); - if (sleep_time > 0) { - event.WaitFor(std::chrono::nanoseconds(sleep_time)); - } + while (!paused && !event.IsSet() && wait_time > 0) { + wait_time = *next_time - GetGlobalTimeNs().count(); - while (!paused && !event.IsSet() && GetGlobalTimeNs().count() < *next_time) { - // Yield to reduce thread starvation. - std::this_thread::yield(); + if (wait_time >= timer_resolution_ns) { + Common::Windows::SleepForOneTick(); + } else { + std::this_thread::yield(); + } } if (event.IsSet()) { @@ -285,9 +289,9 @@ void CoreTiming::ThreadLoop() { } paused_set = true; - clock->Pause(true); + event_clock->Pause(true); pause_event.Wait(); - clock->Pause(false); + event_clock->Pause(false); } } @@ -303,16 +307,23 @@ void CoreTiming::Reset() { has_started = false; } +std::chrono::nanoseconds CoreTiming::GetCPUTimeNs() const { + if (is_multicore) [[likely]] { + return cpu_clock->GetTimeNS(); + } + return CyclesToNs(ticks); +} + std::chrono::nanoseconds CoreTiming::GetGlobalTimeNs() const { - if (is_multicore) { - return clock->GetTimeNS(); + if (is_multicore) [[likely]] { + return event_clock->GetTimeNS(); } return CyclesToNs(ticks); } std::chrono::microseconds CoreTiming::GetGlobalTimeUs() const { - if (is_multicore) { - return clock->GetTimeUS(); + if (is_multicore) [[likely]] { + return event_clock->GetTimeUS(); } return CyclesToUs(ticks); } diff --git a/src/core/core_timing.h b/src/core/core_timing.h index da366637b..4b89c0c39 100644 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -122,6 +122,9 @@ public: /// Returns current time in emulated in Clock cycles u64 GetClockTicks() const; + /// Returns current time in nanoseconds. + std::chrono::nanoseconds GetCPUTimeNs() const; + /// Returns current time in microseconds. std::chrono::microseconds GetGlobalTimeUs() const; @@ -139,7 +142,8 @@ private: void Reset(); - std::unique_ptr<Common::WallClock> clock; + std::unique_ptr<Common::WallClock> cpu_clock; + std::unique_ptr<Common::WallClock> event_clock; s64 global_timer = 0; diff --git a/src/core/hardware_properties.h b/src/core/hardware_properties.h index 45567b840..191c28bb4 100644 --- a/src/core/hardware_properties.h +++ b/src/core/hardware_properties.h @@ -13,11 +13,9 @@ namespace Core { namespace Hardware { -// The below clock rate is based on Switch's clockspeed being widely known as 1.020GHz -// The exact value used is of course unverified. -constexpr u64 BASE_CLOCK_RATE = 1019215872; // Switch cpu frequency is 1020MHz un/docked -constexpr u64 CNTFREQ = 19200000; // Switch's hardware clock speed -constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores +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 // Virtual to Physical core map. constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{ |