To compute the average frequency, two counters are needed : IA32_APERF and IA32_MPERF
According to Intel specifications Volume 3 section 14.5.5, the average frequency is :
delta ((IA32_APERF) / delta (IA32_MPERF)) * (TSC frequency)
According to Volume 3, there are two methods to compute TSC frequency:
1°) To compute "TSC frequency", we need to know the "nominal core crystal clock frequency":
Section 18.7.3 (Volume 3 specifications Intel) says that Nominal TSC frequency is obtained from (CPUID.15H.ECX[31:0] * CPUID.15H.EBX[31:0] ) / (CPUID.15H.EAX[31:0])
2°) To compute "TSC frequency", we can use MSR_PLATFORM_INFO[15 :8]
With the first method (ivy bridge microarchitecture) : "TSC frequency" = ecx*(ebx/eax) = 98889 Hz
Indeed, the output of "cpuid -l0x15" is :
eax = 00000007 (hexa)
ebx = 00000340 (hexa)
ecx = 00000340 (hexa)
With the second method
MSR_PLATFORM_INFO[15 :8] = 20
Indeed, the output of rdmsr 0xCE is :
TSC frequency = 20 * 100 MHz
TSC frequency = 2000 MHz
With the second method, TSC frequency is much more higher (x 10 000) than its value computed with the first method
What is the correct value?
The method based on CPUID is a new one and is probably not supported on a processor as old as Ivy Bridge?
I don't have any CPUID dumps on Ivy Bridge systems, but you should certainly check the value returned in %eax by CPUID with an initial %eax value of 0x0. This will be the maximum %eax value supported for "basic" CPUID information. My systems before Skylake Xeon all have maximum values smaller than 0x15:
On a Cascade Lake Xeon system, CPUID with %eax=0x15 returns
0x00000015 0x00: eax=0x00000002 ebx=0x000000d8 ecx=0x00000000 edx=0x00000000
So even these relatively new processors don't provide information about the "crystal clock frequency" in ECX. The EBX and EAX values show a multiplier of 216/2. Given the known TSC clock of 2700 MHz, these imply a "crystal clock frequency" of 25 MHz.
On the same system, CPUID with EAX=0x16 returns:
0x00000016 0x00: eax=0x00000a8c ebx=0x00000fa0 ecx=0x00000064 edx=0x00000000
EAX gives the CPU base frequency in MHz: 0xa8c = 2700
EBX gives the maximum CPU frequency: 0xfa0 = 4000
ECX gives the "bus" frequency in MHz: 0x64 = 100
Note that the "crystal" frequency and the "bus" frequency are not the same. This is reflected in the behavior of the performance counters for Reference Cycles Not Halted. In previous processors this counter would increment by the CPU multiplier ratio once every "tick" of the "base clock" -- i.e., increment by 27 every 10 nanoseconds (for a 100 MHz base clock). On SKX/CLX, the Reference Cycles Not Halted now increments only once every "crystal clock" cycles -- e.g., with a 2700 MHz TSC and a 25 MHz "crystal clock", the counter increments by 108 every 40 ns.