diff options
author | liamwhite <liamwhite@users.noreply.github.com> | 2023-03-10 19:55:11 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-10 19:55:11 +0100 |
commit | 021af4fd0016c49009e3c1ff51ff73aba75b9eb4 (patch) | |
tree | c589832d3b517d96dae79b7263b92fe69a3457ba /src/common | |
parent | Merge pull request #9916 from liamwhite/fpu (diff) | |
parent | perf_stats: Check multicore first (diff) | |
download | yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.gz yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.bz2 yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.lz yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.xz yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.zst yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.zip |
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/steady_clock.cpp | 25 | ||||
-rw-r--r-- | src/common/steady_clock.h | 11 | ||||
-rw-r--r-- | src/common/x64/native_clock.cpp | 38 | ||||
-rw-r--r-- | src/common/x64/native_clock.h | 5 |
4 files changed, 72 insertions, 7 deletions
diff --git a/src/common/steady_clock.cpp b/src/common/steady_clock.cpp index 0d5908aa7..782859196 100644 --- a/src/common/steady_clock.cpp +++ b/src/common/steady_clock.cpp @@ -23,6 +23,19 @@ static s64 WindowsQueryPerformanceCounter() { QueryPerformanceCounter(&counter); return counter.QuadPart; } + +static s64 GetSystemTimeNS() { + // GetSystemTimePreciseAsFileTime returns the file time in 100ns units. + static constexpr s64 Multiplier = 100; + // Convert Windows epoch to Unix epoch. + static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL; + + FILETIME filetime; + GetSystemTimePreciseAsFileTime(&filetime); + return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) + + static_cast<s64>(filetime.dwLowDateTime)) - + WindowsEpochToUnixEpochNS; +} #endif SteadyClock::time_point SteadyClock::Now() noexcept { @@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept { #endif } +RealTimeClock::time_point RealTimeClock::Now() noexcept { +#if defined(_WIN32) + return time_point{duration{GetSystemTimeNS()}}; +#elif defined(__APPLE__) + return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}}; +#else + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}}; +#endif +} + }; // namespace Common diff --git a/src/common/steady_clock.h b/src/common/steady_clock.h index 9497cf865..dbd0e2513 100644 --- a/src/common/steady_clock.h +++ b/src/common/steady_clock.h @@ -20,4 +20,15 @@ struct SteadyClock { [[nodiscard]] static time_point Now() noexcept; }; +struct RealTimeClock { + using rep = s64; + using period = std::nano; + using duration = std::chrono::nanoseconds; + using time_point = std::chrono::time_point<RealTimeClock>; + + static constexpr bool is_steady = false; + + [[nodiscard]] static time_point Now() noexcept; +}; + } // namespace Common diff --git a/src/common/x64/native_clock.cpp b/src/common/x64/native_clock.cpp index bc1a973b0..76c66e7ee 100644 --- a/src/common/x64/native_clock.cpp +++ b/src/common/x64/native_clock.cpp @@ -53,11 +53,11 @@ u64 EstimateRDTSCFrequency() { FencedRDTSC(); // Get the current time. - const auto start_time = Common::SteadyClock::Now(); + const auto start_time = Common::RealTimeClock::Now(); const u64 tsc_start = FencedRDTSC(); // Wait for 250 milliseconds. std::this_thread::sleep_for(std::chrono::milliseconds{250}); - const auto end_time = Common::SteadyClock::Now(); + const auto end_time = Common::RealTimeClock::Now(); const u64 tsc_end = FencedRDTSC(); // Calculate differences. const u64 timer_diff = static_cast<u64>( @@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen u64 rtsc_frequency_) : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ rtsc_frequency_} { + // Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed. + time_sync_thread = std::jthread{[this](std::stop_token token) { + // Get the current time. + const auto start_time = Common::RealTimeClock::Now(); + const u64 tsc_start = FencedRDTSC(); + // Wait for 10 seconds. + if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) { + return; + } + const auto end_time = Common::RealTimeClock::Now(); + const u64 tsc_end = FencedRDTSC(); + // Calculate differences. + const u64 timer_diff = static_cast<u64>( + std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count()); + const u64 tsc_diff = tsc_end - tsc_start; + const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff); + rtsc_frequency = tsc_freq; + CalculateAndSetFactors(); + }}; + time_point.inner.last_measure = FencedRDTSC(); time_point.inner.accumulated_ticks = 0U; - ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); - us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); - ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); - clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); - cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); + CalculateAndSetFactors(); } u64 NativeClock::GetRTSC() { @@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() { return MultiplyHigh(rtsc_value, cpu_rtsc_factor); } +void NativeClock::CalculateAndSetFactors() { + ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); + us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency); + ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency); + clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency); + cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency); +} + } // namespace X64 } // namespace Common diff --git a/src/common/x64/native_clock.h b/src/common/x64/native_clock.h index 38ae7a462..03ca291d8 100644 --- a/src/common/x64/native_clock.h +++ b/src/common/x64/native_clock.h @@ -3,6 +3,7 @@ #pragma once +#include "common/polyfill_thread.h" #include "common/wall_clock.h" namespace Common { @@ -28,6 +29,8 @@ public: private: u64 GetRTSC(); + void CalculateAndSetFactors(); + union alignas(16) TimePoint { TimePoint() : pack{} {} u128 pack{}; @@ -47,6 +50,8 @@ private: u64 ms_rtsc_factor{}; u64 rtsc_frequency; + + std::jthread time_sync_thread; }; } // namespace X64 |