mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-19 12:40:29 +00:00
TSC calibration improvements
Bind main thread to a single core for calibration. Issue RDTSC after clock probing, may improve accuracy.
This commit is contained in:
parent
76294beae1
commit
d66bdf1653
@ -2,6 +2,7 @@
|
|||||||
#include "StrFmt.h"
|
#include "StrFmt.h"
|
||||||
#include "File.h"
|
#include "File.h"
|
||||||
#include "Emu/system_config.h"
|
#include "Emu/system_config.h"
|
||||||
|
#include "Thread.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
@ -283,37 +284,48 @@ ullong utils::get_tsc_freq()
|
|||||||
return round_tsc(freq.QuadPart * 1024);
|
return round_tsc(freq.QuadPart * 1024);
|
||||||
|
|
||||||
const ullong timer_freq = freq.QuadPart;
|
const ullong timer_freq = freq.QuadPart;
|
||||||
Sleep(1);
|
|
||||||
#else
|
#else
|
||||||
const ullong timer_freq = 1'000'000'000;
|
const ullong timer_freq = 1'000'000'000;
|
||||||
ullong sec_base = 0;
|
|
||||||
usleep(200);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Calibrate TSC
|
// Calibrate TSC
|
||||||
constexpr int samples = 40;
|
constexpr int samples = 40;
|
||||||
ullong rdtsc_data[samples];
|
ullong rdtsc_data[samples];
|
||||||
ullong timer_data[samples];
|
ullong timer_data[samples];
|
||||||
|
ullong error_data[samples];
|
||||||
|
|
||||||
|
// Narrow thread affinity to a single core
|
||||||
|
const u64 old_aff = thread_ctrl::get_thread_affinity_mask();
|
||||||
|
thread_ctrl::set_thread_affinity_mask(old_aff & (0 - old_aff));
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
struct timespec ts0;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &ts0);
|
||||||
|
ullong sec_base = ts0.tv_sec;
|
||||||
|
#endif
|
||||||
|
|
||||||
for (int i = 0; i < samples; i++)
|
for (int i = 0; i < samples; i++)
|
||||||
{
|
{
|
||||||
rdtsc_data[i] = (_mm_lfence(), __rdtsc());
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
Sleep(1);
|
||||||
|
error_data[i] = (_mm_lfence(), __rdtsc());
|
||||||
LARGE_INTEGER ctr;
|
LARGE_INTEGER ctr;
|
||||||
QueryPerformanceCounter(&ctr);
|
QueryPerformanceCounter(&ctr);
|
||||||
|
rdtsc_data[i] = (_mm_lfence(), __rdtsc());
|
||||||
timer_data[i] = ctr.QuadPart;
|
timer_data[i] = ctr.QuadPart;
|
||||||
Sleep(1);
|
|
||||||
#else
|
#else
|
||||||
|
usleep(200);
|
||||||
|
error_data[i] = (_mm_lfence(), __rdtsc());
|
||||||
struct timespec ts;
|
struct timespec ts;
|
||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
if (i == 0)
|
rdtsc_data[i] = (_mm_lfence(), __rdtsc());
|
||||||
sec_base = ts.tv_sec;
|
|
||||||
timer_data[i] = ts.tv_nsec + (ts.tv_sec - sec_base) * 1'000'000'000;
|
timer_data[i] = ts.tv_nsec + (ts.tv_sec - sec_base) * 1'000'000'000;
|
||||||
usleep(200);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Restore main thread affinity
|
||||||
|
thread_ctrl::set_thread_affinity_mask(old_aff);
|
||||||
|
|
||||||
// Compute average TSC
|
// Compute average TSC
|
||||||
ullong acc = 0;
|
ullong acc = 0;
|
||||||
for (int i = 0; i < samples - 1; i++)
|
for (int i = 0; i < samples - 1; i++)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user