I am monitoring an Intel Core i9-9880H in a new Thinkpad X1 Extreme Gen 2. My OS is Linux, using a recent kernel (5.4)
To find the average clock speed of each core over the course of an interval, I am doing this:
1. Read TSC clockspeed (-> 2300MHz)
2. Read mperf and aperf values from MSR 0xe7 and 0xe8
3. Wait interval, read them again
4. average clockspeed = tsc_speed * (aperf-oldaperf)/(mperf-oldmperf)
Is this correct? I'm pretty sure it is. The trouble I'm having is that the highest clock I'm reading with one core under load is pretty much exactly 4600MHz. This CPU however should be capable of reaching 4800MHz according to Ark.
So I was looking at possible reasons that it's not entering the highest frequency. Here's what I tried:
- Other cores might be active, thus limiting the max turbo ratio. For testing purposes, I set the max turbo ratio for 1/2/3/4/5/6/7/8 cores active all to x48 via MSR 0x1ad. However, this register doesn't seem to accept values above the stock values. Any idea why?
- So I disabled all cores but one in the kernel. Other cores can't be active if they're never scheduled by the kernel :) Still stuck at 4600MHz.
- Does the CPU require special drivers? I considered Turbo Boost Max 3.0 aka ITMT. However, the CPU is specced as only having Turbo Boost 2.0, so no. I'm also already using the intel driver (intel_pstate).
- Thermals? No, I have even raised the thermal trip temperature higher, to 97°C, via MSR 0x1a2. The temperature also stays well below that value. It also wouldn't explain why it's stuck at exactly 4600MHz.
- Bidirectional PROCHOT? No, disabled that bit in MSR.
- TDP limits? No, with one core loaded it doesn't even get close to its max TDP of 45W. It also wouldn't explain why it's stuck at exactly 4600MHz.
- Current limits (ICC) not exceeded as far as I can tell
- x86_energy_perf_policy and pstate governor both set to performance
I've run out of ideas. I'd very much like to figure out what I'm doing wrong reading the speed, or if I'm doing things correctly, what is preventing me from reaching the full advertised clockspeed.
Thanks a lot!
MSR_TURBO_RATIO_LIMIT can only be used to specify a *lower* maximum Turbo frequency for each core count. The HW will pick the lower of the default (power-on) value and the programmed value.
What is running on the "core under load"?
Several ideas come to mind:
- It is not documented for the client parts, but on the server parts the maximum Turbo frequency is a function of the instructions being executed. For the instruction sets supported by the Core i9-9880H, running 256-bit AVX arithmetic instructions would slow down a server core.
- If the processor supports "Energy-Efficient Turbo" (and it is enabled), the hardware will monitor the instruction retirement rate and will refrain from boosting the frequency to the maximum available if increasing the frequency does not produce a significant performance improvement.
- This is not well documented, but it is possible that bits 19-20 of MSR_POWER_CTL (0x1fc) may influence the HW policy.
- MSR IA32_ENERGY_PERF_BIAS (0x1b0) may limit maximum Turbo if not set to 0x0 (maximum performance).
- If the processor supports "Hardware-Controlled Performance States" (and they are enabled), the frequency and energy-performance bias are controlled by a different set of MSRs, described in section 14.4 of Volume 3 of the Intel Architecture SW Developer's Manual.