[ntp:questions] Win7: ntpd adjusting time backwards
jmostert at xs4all.nl
Thu Dec 13 00:22:56 UTC 2012
On 2012-12-12 23:40, David Taylor wrote:
> On 12/12/2012 20:58, Jeroen Mostert wrote:
>> Here's some loopstats from a brand new machine running Windows Server 2012:
>> 56273 56211.040 -0.000185248 20.113 0.000065610 0.002127 8
>> 56273 57117.052 0.000487392 20.115 0.000245606 0.002073 8
>> 56273 57381.058 0.000771702 20.115 0.000250771 0.001958 8
>> 56273 58424.072 0.000542051 20.118 0.000248229 0.001977 8
>> 56273 59490.107 0.000320045 20.119 0.000245105 0.001903 8
>> 56273 61613.141 0.000101314 20.120 0.000241965 0.001801 8
>> 56273 62411.152 -0.000139791 20.119 0.000241858 0.001691 8
>> 56273 63476.176 -0.000219043 20.118 0.000227966 0.001611 8
>> 56273 65585.223 -0.000361511 20.116 0.000219111 0.001795 8
>> 56273 66112.226 -0.000879125 20.114 0.000274771 0.001787 8
>> 56273 66382.233 -0.000775453 20.113 0.000259625 0.001694 8
>> 56273 66645.246 -0.000818638 20.112 0.000243336 0.001610 8
>> 56273 68744.282 -0.000901985 20.105 0.000229520 0.002861 8
>> 56273 69007.289 -0.000850863 20.105 0.000215455 0.002693 8
>> 56273 69542.304 -0.000541853 20.103 0.000229247 0.002548 8
>> 56273 69801.304 -0.000579627 20.103 0.000214857 0.002391 8
>> 56273 70070.309 -0.000507633 20.102 0.000202585 0.002244 8
>> 56273 70335.311 -0.000527417 20.102 0.000189630 0.002107 8
>> 56273 72431.353 -0.000577564 20.097 0.000178267 0.002512 8
>> 56273 72968.365 -0.000503697 20.096 0.000168786 0.002377 8
>> This is syncing with Internet time through the NL NTP pool.
>> I've set up four other machines to sync with this server, two virtual
>> and two physical. The virtual machines are running NT 6.0, the physical
>> machines 6.1 (client/server flavors not relevant here). The virtuals do
>> not have the multimedia timer enabled, since I've read that this can
>> negatively affect performance of the host (which makes sense, since
>> driving all virtuals with 1000 interrupts/sec can't be easy). Even so,
>> ntpd achieves sub-millisecond sync with the local server on all of them
>> almost all of the time. I've registered three spikes on the virtual
>> machines so far, of 2, 5 and 10 ms.
>> To say I'm pleased with the results would be an understatement. In fact,
>> I'm now tempted to try and solve the second problem, which is that no
>> matter how accurately ntpd syncs the clock, there is no Windows API
>> which will allow me to read its value with that accuracy! On the 2012
>> Server, GetSystemTimePreciseAsFileTime() is available, but most of our
>> machines are still Windows Server 2008/2008 R2 (even with some 2003
>> server still hanging around). On the physical machines,
>> GetSystemTimeAsFileTime() will get the time with 1 ms resolution since
>> the MM timer will be enabled, which is good enough. On the virtual
>> machines, however, GSTAFT cannot do better than the 15.625 ms resolution
>> it has by default.
>> I suppose it ought to be possible to expose enough of ntpd's internal
>> state through shared memory to reconstruct what it thinks of the time on
>> demand. There are obvious challenges (like appropriate locking and
>> quickly detecting if ntpd has gone away so we can switch back to
>> GSTAFT). I don't suppose anyone has experience with this? :-)
> Yes, that's looking better! I have tried two Win-8/Server-2012 PCs, but only one
> showed that better performance. At least you can get that performance without
> needing a Linux or FreeBSD box.
Yes... but I'm probably getting one anyway, because, well, it's more fun that
way. :-) We had the spare server anyway. And Linux still has a better NTP track
record than Windows, even with the recent improvements.
> There is an issue with getting the time more precisely, and I found some code on
> the Internet which I translated to Delphi and had a play with. Results are here:
> original page:
> Perhaps something like that will help you? But please check it carefully!
That looks promising, I'll look into it. The calibration stuff looks fiddly,
though, I'd need to automate that effectively before I could put it into
We should be able to do even better by simply calling the
get_sys_time_as_filetime pointer from nt_clockstuff.c, which will point to
either GetSystemTimePreciseAsFileTime(), GetSystemTimeAsFileTime() or ntpd's own
GetInterpTimeAsFileTime() routine, depending on what the OS supports. That would
use ntpd's own interpolation if interpolation is being used, which has proven to
be highly trustworthy (in my case, at least, I understand mileage varies). The
basic approach cannot reliably get sub-millisecond timestamps (since the best
GSTAFT can do is a millisecond-accurate timestamp if the MM timer is active) but
I don't need that anyway.
In theory, I could just extract the NT code from ntpd (minus clock disciplining,
of course) and see how well it works when it's not running in a realtime thread,
but I suspect the answer is "not at all". It looks incredibly tight. Even so it
should be possible to have ntpd do the fiddly stuff with realtime threads and
keep the results that can't be replicated in shared memory.
I definitely need to effectively steal other people's code, because if I
actually dug in and spent time to understand this stuff well enough to write my
own code I suspect I might as well kiss Christmas goodbye. I probably need to
remind myself that I have already met the original goal and then some.
> Virtual PCs are another issue altogether, of course.
Yes, on the plus side, VMs running on the same host have almost identical drift
and network characteristics; on the negative side it's easy for a VM to slip out
of sync when there's load.
More information about the questions