summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar liamwhite2023-03-10 13:55:11 -0500
committerGravatar GitHub2023-03-10 13:55:11 -0500
commit021af4fd0016c49009e3c1ff51ff73aba75b9eb4 (patch)
treec589832d3b517d96dae79b7263b92fe69a3457ba /src
parentMerge pull request #9916 from liamwhite/fpu (diff)
parentperf_stats: Check multicore first (diff)
downloadyuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.gz
yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.tar.xz
yuzu-021af4fd0016c49009e3c1ff51ff73aba75b9eb4.zip
Merge pull request #9917 from Morph1984/the-real-time
native_clock: Re-adjust the RDTSC frequency to its real frequency
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/renderer/adsp/audio_renderer.cpp2
-rw-r--r--src/common/steady_clock.cpp25
-rw-r--r--src/common/steady_clock.h11
-rw-r--r--src/common/x64/native_clock.cpp38
-rw-r--r--src/common/x64/native_clock.h5
-rw-r--r--src/core/core_timing.cpp2
-rw-r--r--src/core/cpu_manager.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp8
-rw-r--r--src/core/perf_stats.cpp4
-rw-r--r--src/video_core/gpu_thread.cpp2
11 files changed, 83 insertions, 18 deletions
diff --git a/src/audio_core/renderer/adsp/audio_renderer.cpp b/src/audio_core/renderer/adsp/audio_renderer.cpp
index 78c15629b..0e437e779 100644
--- a/src/audio_core/renderer/adsp/audio_renderer.cpp
+++ b/src/audio_core/renderer/adsp/audio_renderer.cpp
@@ -135,7 +135,7 @@ void AudioRenderer::ThreadFunc() {
135 static constexpr char name[]{"AudioRenderer"}; 135 static constexpr char name[]{"AudioRenderer"};
136 MicroProfileOnThreadCreate(name); 136 MicroProfileOnThreadCreate(name);
137 Common::SetCurrentThreadName(name); 137 Common::SetCurrentThreadName(name);
138 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); 138 Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
139 if (mailbox->ADSPWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) { 139 if (mailbox->ADSPWaitMessage() != RenderMessage::AudioRenderer_InitializeOK) {
140 LOG_ERROR(Service_Audio, 140 LOG_ERROR(Service_Audio,
141 "ADSP Audio Renderer -- Failed to receive initialize message from host!"); 141 "ADSP Audio Renderer -- Failed to receive initialize message from host!");
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() {
23 QueryPerformanceCounter(&counter); 23 QueryPerformanceCounter(&counter);
24 return counter.QuadPart; 24 return counter.QuadPart;
25} 25}
26
27static s64 GetSystemTimeNS() {
28 // GetSystemTimePreciseAsFileTime returns the file time in 100ns units.
29 static constexpr s64 Multiplier = 100;
30 // Convert Windows epoch to Unix epoch.
31 static constexpr s64 WindowsEpochToUnixEpochNS = 0x19DB1DED53E8000LL;
32
33 FILETIME filetime;
34 GetSystemTimePreciseAsFileTime(&filetime);
35 return Multiplier * ((static_cast<s64>(filetime.dwHighDateTime) << 32) +
36 static_cast<s64>(filetime.dwLowDateTime)) -
37 WindowsEpochToUnixEpochNS;
38}
26#endif 39#endif
27 40
28SteadyClock::time_point SteadyClock::Now() noexcept { 41SteadyClock::time_point SteadyClock::Now() noexcept {
@@ -53,4 +66,16 @@ SteadyClock::time_point SteadyClock::Now() noexcept {
53#endif 66#endif
54} 67}
55 68
69RealTimeClock::time_point RealTimeClock::Now() noexcept {
70#if defined(_WIN32)
71 return time_point{duration{GetSystemTimeNS()}};
72#elif defined(__APPLE__)
73 return time_point{duration{clock_gettime_nsec_np(CLOCK_REALTIME)}};
74#else
75 timespec ts;
76 clock_gettime(CLOCK_REALTIME, &ts);
77 return time_point{std::chrono::seconds{ts.tv_sec} + std::chrono::nanoseconds{ts.tv_nsec}};
78#endif
79}
80
56}; // namespace Common 81}; // 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 {
20 [[nodiscard]] static time_point Now() noexcept; 20 [[nodiscard]] static time_point Now() noexcept;
21}; 21};
22 22
23struct RealTimeClock {
24 using rep = s64;
25 using period = std::nano;
26 using duration = std::chrono::nanoseconds;
27 using time_point = std::chrono::time_point<RealTimeClock>;
28
29 static constexpr bool is_steady = false;
30
31 [[nodiscard]] static time_point Now() noexcept;
32};
33
23} // namespace Common 34} // 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() {
53 FencedRDTSC(); 53 FencedRDTSC();
54 54
55 // Get the current time. 55 // Get the current time.
56 const auto start_time = Common::SteadyClock::Now(); 56 const auto start_time = Common::RealTimeClock::Now();
57 const u64 tsc_start = FencedRDTSC(); 57 const u64 tsc_start = FencedRDTSC();
58 // Wait for 250 milliseconds. 58 // Wait for 250 milliseconds.
59 std::this_thread::sleep_for(std::chrono::milliseconds{250}); 59 std::this_thread::sleep_for(std::chrono::milliseconds{250});
60 const auto end_time = Common::SteadyClock::Now(); 60 const auto end_time = Common::RealTimeClock::Now();
61 const u64 tsc_end = FencedRDTSC(); 61 const u64 tsc_end = FencedRDTSC();
62 // Calculate differences. 62 // Calculate differences.
63 const u64 timer_diff = static_cast<u64>( 63 const u64 timer_diff = static_cast<u64>(
@@ -72,13 +72,29 @@ NativeClock::NativeClock(u64 emulated_cpu_frequency_, u64 emulated_clock_frequen
72 u64 rtsc_frequency_) 72 u64 rtsc_frequency_)
73 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{ 73 : WallClock(emulated_cpu_frequency_, emulated_clock_frequency_, true), rtsc_frequency{
74 rtsc_frequency_} { 74 rtsc_frequency_} {
75 // Thread to re-adjust the RDTSC frequency after 10 seconds has elapsed.
76 time_sync_thread = std::jthread{[this](std::stop_token token) {
77 // Get the current time.
78 const auto start_time = Common::RealTimeClock::Now();
79 const u64 tsc_start = FencedRDTSC();
80 // Wait for 10 seconds.
81 if (!Common::StoppableTimedWait(token, std::chrono::seconds{10})) {
82 return;
83 }
84 const auto end_time = Common::RealTimeClock::Now();
85 const u64 tsc_end = FencedRDTSC();
86 // Calculate differences.
87 const u64 timer_diff = static_cast<u64>(
88 std::chrono::duration_cast<std::chrono::nanoseconds>(end_time - start_time).count());
89 const u64 tsc_diff = tsc_end - tsc_start;
90 const u64 tsc_freq = MultiplyAndDivide64(tsc_diff, 1000000000ULL, timer_diff);
91 rtsc_frequency = tsc_freq;
92 CalculateAndSetFactors();
93 }};
94
75 time_point.inner.last_measure = FencedRDTSC(); 95 time_point.inner.last_measure = FencedRDTSC();
76 time_point.inner.accumulated_ticks = 0U; 96 time_point.inner.accumulated_ticks = 0U;
77 ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency); 97 CalculateAndSetFactors();
78 us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
79 ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
80 clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
81 cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
82} 98}
83 99
84u64 NativeClock::GetRTSC() { 100u64 NativeClock::GetRTSC() {
@@ -138,6 +154,14 @@ u64 NativeClock::GetCPUCycles() {
138 return MultiplyHigh(rtsc_value, cpu_rtsc_factor); 154 return MultiplyHigh(rtsc_value, cpu_rtsc_factor);
139} 155}
140 156
157void NativeClock::CalculateAndSetFactors() {
158 ns_rtsc_factor = GetFixedPoint64Factor(NS_RATIO, rtsc_frequency);
159 us_rtsc_factor = GetFixedPoint64Factor(US_RATIO, rtsc_frequency);
160 ms_rtsc_factor = GetFixedPoint64Factor(MS_RATIO, rtsc_frequency);
161 clock_rtsc_factor = GetFixedPoint64Factor(emulated_clock_frequency, rtsc_frequency);
162 cpu_rtsc_factor = GetFixedPoint64Factor(emulated_cpu_frequency, rtsc_frequency);
163}
164
141} // namespace X64 165} // namespace X64
142 166
143} // namespace Common 167} // 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 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "common/polyfill_thread.h"
6#include "common/wall_clock.h" 7#include "common/wall_clock.h"
7 8
8namespace Common { 9namespace Common {
@@ -28,6 +29,8 @@ public:
28private: 29private:
29 u64 GetRTSC(); 30 u64 GetRTSC();
30 31
32 void CalculateAndSetFactors();
33
31 union alignas(16) TimePoint { 34 union alignas(16) TimePoint {
32 TimePoint() : pack{} {} 35 TimePoint() : pack{} {}
33 u128 pack{}; 36 u128 pack{};
@@ -47,6 +50,8 @@ private:
47 u64 ms_rtsc_factor{}; 50 u64 ms_rtsc_factor{};
48 51
49 u64 rtsc_frequency; 52 u64 rtsc_frequency;
53
54 std::jthread time_sync_thread;
50}; 55};
51} // namespace X64 56} // namespace X64
52 57
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 742cfb996..cd4df4522 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -53,7 +53,7 @@ void CoreTiming::ThreadEntry(CoreTiming& instance) {
53 static constexpr char name[] = "HostTiming"; 53 static constexpr char name[] = "HostTiming";
54 MicroProfileOnThreadCreate(name); 54 MicroProfileOnThreadCreate(name);
55 Common::SetCurrentThreadName(name); 55 Common::SetCurrentThreadName(name);
56 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical); 56 Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
57 instance.on_thread_init(); 57 instance.on_thread_init();
58 instance.ThreadLoop(); 58 instance.ThreadLoop();
59 MicroProfileOnThreadExit(); 59 MicroProfileOnThreadExit();
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp
index 04a11f444..980bb97f9 100644
--- a/src/core/cpu_manager.cpp
+++ b/src/core/cpu_manager.cpp
@@ -192,7 +192,7 @@ void CpuManager::RunThread(std::stop_token token, std::size_t core) {
192 } 192 }
193 MicroProfileOnThreadCreate(name.c_str()); 193 MicroProfileOnThreadCreate(name.c_str());
194 Common::SetCurrentThreadName(name.c_str()); 194 Common::SetCurrentThreadName(name.c_str());
195 Common::SetCurrentThreadPriority(Common::ThreadPriority::High); 195 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
196 auto& data = core_data[core]; 196 auto& data = core_data[core];
197 data.host_context = Common::Fiber::ThreadToFiber(); 197 data.host_context = Common::Fiber::ThreadToFiber();
198 198
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
index df9ee0c3f..9e2f3ab21 100644
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ b/src/core/hle/service/hid/controllers/stubbed.cpp
@@ -26,7 +26,7 @@ void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
26 } 26 }
27 27
28 CommonHeader header{}; 28 CommonHeader header{};
29 header.timestamp = core_timing.GetCPUTicks(); 29 header.timestamp = core_timing.GetGlobalTimeNs().count();
30 header.total_entry_count = 17; 30 header.total_entry_count = 17;
31 header.entry_count = 0; 31 header.entry_count = 0;
32 header.last_entry_index = 0; 32 header.last_entry_index = 0;
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index d90a4e732..3ef91df4b 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -32,7 +32,7 @@ void Controller_Touchscreen::OnInit() {}
32void Controller_Touchscreen::OnRelease() {} 32void Controller_Touchscreen::OnRelease() {}
33 33
34void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) { 34void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
35 shared_memory->touch_screen_lifo.timestamp = core_timing.GetCPUTicks(); 35 shared_memory->touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
36 36
37 if (!IsControllerActivated()) { 37 if (!IsControllerActivated()) {
38 shared_memory->touch_screen_lifo.buffer_count = 0; 38 shared_memory->touch_screen_lifo.buffer_count = 0;
@@ -85,7 +85,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
85 const auto active_fingers_count = 85 const auto active_fingers_count =
86 static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); 86 static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter));
87 87
88 const u64 tick = core_timing.GetCPUTicks(); 88 const u64 timestamp = static_cast<u64>(core_timing.GetGlobalTimeNs().count());
89 const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state; 89 const auto& last_entry = shared_memory->touch_screen_lifo.ReadCurrentEntry().state;
90 90
91 next_state.sampling_number = last_entry.sampling_number + 1; 91 next_state.sampling_number = last_entry.sampling_number + 1;
@@ -102,8 +102,8 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin
102 touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; 102 touch_entry.diameter_x = Settings::values.touchscreen.diameter_x;
103 touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; 103 touch_entry.diameter_y = Settings::values.touchscreen.diameter_y;
104 touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; 104 touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle;
105 touch_entry.delta_time = tick - active_fingers[id].last_touch; 105 touch_entry.delta_time = timestamp - active_fingers[id].last_touch;
106 fingers[active_fingers[id].id].last_touch = tick; 106 fingers[active_fingers[id].id].last_touch = timestamp;
107 touch_entry.finger = active_fingers[id].id; 107 touch_entry.finger = active_fingers[id].id;
108 touch_entry.attribute.raw = active_fingers[id].attribute.raw; 108 touch_entry.attribute.raw = active_fingers[id].attribute.raw;
109 } else { 109 } else {
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp
index f09c176f8..1231c0dc8 100644
--- a/src/core/perf_stats.cpp
+++ b/src/core/perf_stats.cpp
@@ -126,8 +126,8 @@ double PerfStats::GetLastFrameTimeScale() const {
126} 126}
127 127
128void SpeedLimiter::DoSpeedLimiting(microseconds current_system_time_us) { 128void SpeedLimiter::DoSpeedLimiting(microseconds current_system_time_us) {
129 if (!Settings::values.use_speed_limit.GetValue() || 129 if (Settings::values.use_multi_core.GetValue() ||
130 Settings::values.use_multi_core.GetValue()) { 130 !Settings::values.use_speed_limit.GetValue()) {
131 return; 131 return;
132 } 132 }
133 133
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 9c103c0d4..050b11874 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -25,7 +25,7 @@ static void RunThread(std::stop_token stop_token, Core::System& system,
25 SCOPE_EXIT({ MicroProfileOnThreadExit(); }); 25 SCOPE_EXIT({ MicroProfileOnThreadExit(); });
26 26
27 Common::SetCurrentThreadName(name.c_str()); 27 Common::SetCurrentThreadName(name.c_str());
28 Common::SetCurrentThreadPriority(Common::ThreadPriority::High); 28 Common::SetCurrentThreadPriority(Common::ThreadPriority::Critical);
29 system.RegisterHostThread(); 29 system.RegisterHostThread();
30 30
31 auto current_context = context.Acquire(); 31 auto current_context = context.Acquire();