From c70c08bb07f14e848e62d225d4c09ab55ea6067c Mon Sep 17 00:00:00 2001 From: elad335 <18193363+elad335@users.noreply.github.com> Date: Thu, 24 Oct 2024 13:01:40 +0300 Subject: [PATCH] utils: Make get_tsc_freq() inlined and non-blocking --- rpcs3/main.cpp | 2 +- rpcs3/util/sysinfo.cpp | 23 +++++++++++++++++------ rpcs3/util/sysinfo.hpp | 11 +++++++++-- 3 files changed, 27 insertions(+), 9 deletions(-) diff --git a/rpcs3/main.cpp b/rpcs3/main.cpp index 5bf39052eb..d6124407f0 100644 --- a/rpcs3/main.cpp +++ b/rpcs3/main.cpp @@ -554,7 +554,7 @@ int main(int argc, char** argv) ensure(thread_ctrl::is_main(), "Not main thread"); // Initialize TSC freq (in case it isn't) - static_cast(utils::get_tsc_freq()); + static_cast(utils::ensure_tsc_freq_init()); // Initialize thread pool finalizer (on first use) static_cast(named_thread("", [](int) {})); diff --git a/rpcs3/util/sysinfo.cpp b/rpcs3/util/sysinfo.cpp index 5514f3e5a2..9673c17f8f 100755 --- a/rpcs3/util/sysinfo.cpp +++ b/rpcs3/util/sysinfo.cpp @@ -739,7 +739,12 @@ static constexpr ullong round_tsc(ullong val) return utils::rounded_div(val, 1'000'000) * 1'000'000; } -ullong utils::get_tsc_freq() +namespace utils +{ + u64 s_tsc_freq = 0; +} + +named_thread> s_thread_evaluate_tsc_freq("TSX Evaluate Thread", []() { static const ullong cal_tsc = []() -> ullong { @@ -749,7 +754,7 @@ ullong utils::get_tsc_freq() return r; #endif - if (!has_invariant_tsc()) + if (!utils::has_invariant_tsc()) return 0; #ifdef _WIN32 @@ -766,7 +771,7 @@ ullong utils::get_tsc_freq() #endif // Calibrate TSC - constexpr int samples = 40; + constexpr int samples = 60; ullong rdtsc_data[samples]; ullong timer_data[samples]; [[maybe_unused]] ullong error_data[samples]; @@ -784,14 +789,14 @@ ullong utils::get_tsc_freq() for (int i = 0; i < samples; i++) { #ifdef _WIN32 - Sleep(1); + Sleep(2); error_data[i] = (utils::lfence(), utils::get_tsc()); LARGE_INTEGER ctr; QueryPerformanceCounter(&ctr); rdtsc_data[i] = (utils::lfence(), utils::get_tsc()); timer_data[i] = ctr.QuadPart; #else - usleep(200); + usleep(500); error_data[i] = (utils::lfence(), utils::get_tsc()); struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); @@ -814,7 +819,13 @@ ullong utils::get_tsc_freq() return round_tsc(acc / (samples - 1)); }(); - return cal_tsc; + atomic_storage::release(utils::s_tsc_freq, cal_tsc); +}); + +void utils::ensure_tsc_freq_init() +{ + // Join thread + s_thread_evaluate_tsc_freq(); } u64 utils::get_total_memory() diff --git a/rpcs3/util/sysinfo.hpp b/rpcs3/util/sysinfo.hpp index d7c7c2ec0e..5c38d433f0 100755 --- a/rpcs3/util/sysinfo.hpp +++ b/rpcs3/util/sysinfo.hpp @@ -73,8 +73,6 @@ namespace utils bool get_low_power_mode(); - ullong get_tsc_freq(); - u64 get_total_memory(); u32 get_thread_count(); @@ -89,4 +87,13 @@ namespace utils u64 _get_main_tid(); inline const u64 main_tid = _get_main_tid(); + + extern u64 s_tsc_freq; + + inline ullong get_tsc_freq() + { + return s_tsc_freq; + } + + void ensure_tsc_freq_init(); }