summaryrefslogtreecommitdiff
path: root/src/common/x64/cpu_detect.cpp
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2022-07-16 23:14:38 -0700
committerGitHub <noreply@github.com>2022-07-16 23:14:38 -0700
commit8ca8281f4f2d4050ec4eb67db422d5ceb3cabb3a (patch)
tree10fc191d058f7d057cbe41bc875054080774893d /src/common/x64/cpu_detect.cpp
parent7d66f8339e4243c74c54b43cfbc3e944fbecb3e8 (diff)
parente71d457af923f373505729fe5a335e6768f6144a (diff)
Merge pull request #8543 from BreadFish64/use_tsc_from_caps
common/x64: Use TSC clock rate from CPUID when available
Diffstat (limited to 'src/common/x64/cpu_detect.cpp')
-rw-r--r--src/common/x64/cpu_detect.cpp16
1 files changed, 16 insertions, 0 deletions
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 322aa1f08..1a27532d4 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -161,6 +161,22 @@ static CPUCaps Detect() {
caps.invariant_tsc = Common::Bit<8>(cpu_id[3]);
}
+ if (max_std_fn >= 0x15) {
+ __cpuid(cpu_id, 0x15);
+ caps.tsc_crystal_ratio_denominator = cpu_id[0];
+ caps.tsc_crystal_ratio_numerator = cpu_id[1];
+ caps.crystal_frequency = cpu_id[2];
+ // Some CPU models might not return a crystal frequency.
+ // The CPU model can be detected to use the values from turbostat
+ // https://github.com/torvalds/linux/blob/master/tools/power/x86/turbostat/turbostat.c#L5569
+ // but it's easier to just estimate the TSC tick rate for these cases.
+ if (caps.tsc_crystal_ratio_denominator) {
+ caps.tsc_frequency = static_cast<u64>(caps.crystal_frequency) *
+ caps.tsc_crystal_ratio_numerator /
+ caps.tsc_crystal_ratio_denominator;
+ }
+ }
+
if (max_std_fn >= 0x16) {
__cpuid(cpu_id, 0x16);
caps.base_frequency = cpu_id[0];