Hi--

On Feb 11, 2012, at 12:11 AM, Terje Mathisen wrote:
>> In this specific case, the minimum time to read the clock was measured
>> at ntpd startup to be 114 usec, so each raw OS clock reading is
> 
> OK, that's the problem right there: That value is obviously wrong!
> 
> The Win* OS clock is so dead simple to read that I would expect the minimum 
> reading time to be well below a us!
> 
> Even though the clock is maintained by the HAL, and therefore impossible to 
> fix properly, even with a regular driver, the read interface should be 
> effectively a usermode function call with a single load/store operation:
> 
> I.e. GetSystemTimeAsFTime(&LARGE_INTEGER) could look like this:
> 
> int GetSystemTimeAsFTime(&LARGE_INTEGER tstamp)
> {
>    if (!LARGE_INTEGER) return 0;
>    *tstamp = _kSystemClockCurrentValue; // ??? Some kernel RO value
>    return 1;
> }
> 
> The variable is named something else of course, but since Win* doesn't even 
> try to report an interpolated clock value, it can in principle be almost as 
> simple as that.

> 
> Have you tried to time the minimum clock reading time with RDTSC or 
> GetPerformance* counter calls?
> 
> I wrote a tiny test program on my Win7-64 laptop, it got:
> 
> Reading the system clock 10000000 times, minimum reading time = 24 clock 
> cycles,
> minimum OS step = 0 ticks, maximum OS step = 10000 ticks
> 
> The clock frequency is 2.7 GHz or so, the FileTime ticks should be 100 ns 
> each, so my OS clock is making 1 ms steps, while the clock reading time is 
> down to less than 10 ns!

Well, the code above is not reading a clock; you're reading the stored value of 
what time it was when the kernel's scheduler last updated that value.  When the 
OS scheduler ticks, it reads a clock, then trims down the precision to the 
scheduler quantum (ie, 1ms for HZ=1000), and stores in a "commpage", which is 
mapped RO into userland processes.  

>From what I recall, ntpd tries to notice this limited precision, and adds 
>dithering or "fuzz" to the low bits.

Also please note that you can't just call rdtsc by itself and get good results. 
 At the very least, you want to put a serializing instruction like cpuid first, 
and secondly, you really want to call rdtsc three times, and verify that t1 <= 
t2 <= t3, otherwise you have a chance of getting bogus time results due to your 
thread switching to another processor core between calls, CPU power-state 
changes, chipset bugs, interference from SMC interrupts, and PHK knows what 
else.  :-)

To resurrect timings of various clock-sources taken from 2005:

                TSC             ACPI-fast       HPET            i8254
dual Xeon:      580 nsec        1429 nsec       1120 nsec       3980 nsec
dual Opteron:   212 nsec        1270 nsec       1760 nsec       4420 nsec

Regards,
-- 
-Chuck

_______________________________________________
questions mailing list
[email protected]
http://lists.ntp.org/listinfo/questions

Reply via email to