Performance counter frequency?

#1
Trying to work with microsecond precision (and trying to get good accuracy out of it) has led me to discover that the performance counter's frequency isn't rock-steady (no surprise) and may not be what Windows says it is. So I wrote a little app to measure it. Here, the difference between the Windows reported frequency and my measured frequency accounts for a 5.5 second/day drift between the performance counter and the system clock. When I use my measured value in place of the Windows-reported value I can get very accurate absolute times.

My experience has been that measuring the frequency isn't too hard but ...
(1) I can't do it very well in the few seconds Windows has at start-up time, and
(2) I don't get a good measurement on the first try.
That may be due to my lack of knowledge and/or skill, but if Windows must measure it and has those same difficulties, it's no surprise that Windows doesn't get it perfect.
On my two computers I get consistent results like these.
Code:
l:\projects\perffreq\release> perffreq.exe

Intel(R) Core(TM)2 Quad CPU  Q6700  @ 2.66GHz

2597695 is the performanve counter frequency reported by Windows.

Measured frequencies follow, one per minute.  Stop with Ctrl-C.

2597532
2597526 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
2597529 (average = 2597529)
Code:
v:\> perffreq.exe

Intel(R) Xeon(R) CPU  E5506  @ 2.13GHz

2083388 is the performanve counter frequency reported by Windows.

Measured frequencies follow, one per minute.  Stop with Ctrl-C.

2083246
2083246 (average = 2083246)
2083241 (average = 2083244)
2083248 (average = 2083245)
2083243 (average = 2083245)
2083246 (average = 2083245)
2083234 (average = 2083243)
2083249 (average = 2083244)
2083244 (average = 2083244)
2083244 (average = 2083244)
2083245 (average = 2083244)
2083243 (average = 2083244)
2083246 (average = 2083244)
I have attaches a zipped copy of the 32-bit app (all I have right now) in case anyone's curious. I am curious to hear the results of others.
 

Attachments

#4
My work computer.
Code:
11:06:54 $ perffreq.exe

Intel(R) Xeon(R) CPU            5150  @ 2.66GHz

3579545 is the performanve counter frequency reported by Windows.

Measured frequencies follow, one per minute.  Stop with Ctrl-C.

3579467
3579468 (average = 3579468)
3579469 (average = 3579468)
3579466 (average = 3579468)
3579467 (average = 3579467)
3579468 (average = 3579468)
3579467 (average = 3579467)
3579468 (average = 3579468)
3579468 (average = 3579468)
3579468 (average = 3579468)
 
#6
That's pretty solid. And the Windows estimate is high. That has been my experience ... if you don't measure over a sufficiently long period, you get a high estimate. The app has evolved a lot. And I've built it for X64. If you're interested, I'll post new ones (when it stops evolving).
Code:
PERFFREQ [/N n] [/D n] [/W n] [/Q] [/F] [/A]

/N(umber)  make n estimates (default 1, limit 100)
/D(uration)  make estimates of n seconds (default 60, limit 3600)
/W(armup)  warm up for n milliseconds (default 1000, limit 10000)
/Q(uiet)  output measurements only
/F(requency)  output the Windows frequency (and exit)
/A(verages)  do NOT show averages for multiple measurements
*  n > 0
*  use Ctrl-C to abort
My Zeon at work:
Code:
v:\> perffreq.exe /d 30 /n 5

Intel(R) Xeon(R) CPU  E5506  @ 2.13GHz

2083388 is the performance counter frequency reported by Windows.

1000 millisecond warmup, then 5 30-second measurements ...

2083245
2083248 (average = 2083247)
2083243 (average = 2083245)
2083245 (average = 2083245)
2083239 (average = 2083244)
 
#7
The app has evolved a lot. And I've built it for X64.
I'm running my home computer on Win 8.1 X64, so, yeah, I'm going to try it here. My work PC is still running XP 32bit (I have no choice in that matter).

Edit: Apparently "X64" didn't recognize my processor under Win 8.1...
Code:
[C:\temp]f:\perffreq.exe

Intel(R) Core(TM)2 Quad CPU           @ 2.66GHz

2864583 is the performanve counter frequency reported by Windows.

Measured frequencies follow, one per minute.  Stop with Ctrl-C.

2864584
2864586 (average = 2864585)
2864582 (average = 2864584)
2864582 (average = 2864584)
2864588 (average = 2864584)
2864578 (average = 2864583)
2864583 (average = 2864583)
2864583 (average = 2864583)
2864581 (average = 2864583)
2864582 (average = 2864583)
 
Last edited:
#9
I don't know what you mean by "Edit: Apparently "X64" didn't recognize my processor under Win 8.1...".
It didn't show my processor as being a Q6700 as yours did, nor did it report it running at 2.93GHz. Although I can see where that might be coming from. If I look at my computer properties, it shows my processor as running at 2.93, but identifies it as 2.66.

I'll try the 64-bit version tonight.
 
#10
It didn't show my processor as being a Q6700 as yours did, nor did it report it running at 2.93GHz. Although I can see where that might be coming from. If I look at my computer properties, it shows my processor as running at 2.93, but identifies it as 2.66.

I'll try the 64-bit version tonight.
Was the first line just missing? It just looks for the value of L"ProcessorNameString" in L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0" in HKLM. If that fails it quietly proceeds. I know there's some registry misdirection in WinX64 but I don't know the details. And I'm a little surprised that "Properties" shows the over-clocking. I wonder if Windows *measures* the CPU frequency or if the CPU reports its over-clocked frequency. With a change (or addition) or 4 lines of code, I could get PERFFREQ to do CPUFREQ instead (or in addition).
 
#11
And after also measuring the CPU frequency, it's no surprise that ...
Code:
v:\> freaks.exe
PERF  2597529
CPU  2659869803

v:\> eval 2659869803 / 2597529=4
1024.0000
That's a (the?) typical relationship between the two.
 
#12
Here's a screenshot of My Computer > Properties. I guess it doesn't recognize it as a Q6700 either. Wonder if maybe the motherboard doesn't allow reporting. Notice though that it is @ 2.66GHz and then followed by 2.93GHz (which is what it is overclocked to).
upload_2014-6-25_20-50-46.png