mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-04 22:11:26 +12:00
Implement TSC calibration
Try to get rough TSC frequency by sampling it.
This commit is contained in:
parent
b6e52ad975
commit
15f01a1bf6
1 changed files with 61 additions and 13 deletions
|
@ -131,13 +131,9 @@ std::string utils::get_system_info()
|
||||||
|
|
||||||
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
fmt::append(result, "%s | %d Threads | %.2f GiB RAM", brand, num_proc, mem_total / (1024.0f * 1024 * 1024));
|
||||||
|
|
||||||
if (!has_invariant_tsc())
|
if (const ullong tsc_freq = get_tsc_freq())
|
||||||
{
|
{
|
||||||
fmt::append(result, " | TSC: Bad");
|
fmt::append(result, " | TSC: %.06fGHz", tsc_freq / 1000000000.);
|
||||||
}
|
|
||||||
else if (const ullong tsc_freq = get_tsc_freq())
|
|
||||||
{
|
|
||||||
fmt::append(result, " | TSC: %.02fGHz", tsc_freq / 1000000000.);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -268,15 +264,67 @@ std::string utils::get_OS_version()
|
||||||
|
|
||||||
ullong utils::get_tsc_freq()
|
ullong utils::get_tsc_freq()
|
||||||
{
|
{
|
||||||
|
const ullong cal_tsc = []() -> ullong
|
||||||
|
{
|
||||||
|
if (!has_invariant_tsc())
|
||||||
|
return 0;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
LARGE_INTEGER freq;
|
LARGE_INTEGER freq;
|
||||||
if (!QueryPerformanceFrequency(&freq) || freq.QuadPart > 9'999'999)
|
if (!QueryPerformanceFrequency(&freq))
|
||||||
return 0;
|
return 0;
|
||||||
return freq.QuadPart * 1024;
|
|
||||||
|
if (freq.QuadPart <= 9'999'999)
|
||||||
|
return freq.QuadPart * 1024;
|
||||||
|
|
||||||
|
const ullong timer_freq = freq.QuadPart;
|
||||||
|
Sleep(1);
|
||||||
#else
|
#else
|
||||||
// TODO
|
const ullong timer_freq = 1'000'000'000;
|
||||||
return 0;
|
ullong sec_base = 0;
|
||||||
|
usleep(200);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Calibrate TSC
|
||||||
|
constexpr int samples = 40;
|
||||||
|
ullong rdtsc_data[samples];
|
||||||
|
ullong timer_data[samples];
|
||||||
|
ullong rdtsc_diff[samples - 1];
|
||||||
|
ullong timer_diff[samples - 1];
|
||||||
|
|
||||||
|
for (int i = 0; i < samples; i++)
|
||||||
|
{
|
||||||
|
rdtsc_data[i] = __rdtsc();
|
||||||
|
if (i > 0)
|
||||||
|
rdtsc_diff[i - 1] = rdtsc_data[i] - rdtsc_data[i - 1];
|
||||||
|
#ifdef _WIN32
|
||||||
|
LARGE_INTEGER ctr;
|
||||||
|
QueryPerformanceCounter(&ctr);
|
||||||
|
timer_data[i] = ctr.QuadPart;
|
||||||
|
Sleep(1);
|
||||||
|
#else
|
||||||
|
struct timespec ts;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
|
if (i == 0)
|
||||||
|
sec_base = ts.tv_sec;
|
||||||
|
timer_data[i] = ts.tv_nsec + (ts.tv_sec - sec_base) * 1'000'000'000;
|
||||||
|
usleep(200);
|
||||||
|
#endif
|
||||||
|
if (i > 0)
|
||||||
|
timer_diff[i - 1] = timer_data[i] - timer_data[i - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute average TSC
|
||||||
|
ullong acc = 0;
|
||||||
|
for (int i = 0; i < samples - 1; i++)
|
||||||
|
{
|
||||||
|
acc += rdtsc_diff[i] * timer_freq / timer_diff[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rounding
|
||||||
|
return acc / (samples - 1);
|
||||||
|
}();
|
||||||
|
|
||||||
|
return cal_tsc;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 utils::get_total_memory()
|
u64 utils::get_total_memory()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue