Windows 的时间服务器同步精度是多少?(它会补偿 ping 时间吗?)

Windows 的时间服务器同步精度是多少?(它会补偿 ping 时间吗?)

对于应用程序中描述的项目这个问题我需要尽可能高的时钟精度,而一个解决方案就是精确同步计算机的实时时钟

  1. 与 Windows 7 同步的记录精度是多少调整日期/时间 > 互联网时间 > 更改设置 > 立即更新...

  2. 更具体地说,它是否补偿时间服务器的 ping?

    例子:

    • 时间服务器发送一个数据包,表示现在是 12:00:00.000
    • 假设我的电脑到时间服务器的平均 ping 时间为 93 毫秒(即,在最后一分钟计算的平均 ping 时间)
    • 来自时间服务器的数据包将在 12:00:00.093 到达我的电脑,对吗?
    • 然后是 Windows应该将时间设置为 12:00:00.093 而不是 12:00:00.000,对吗?
  3. 如果没有,是否有一个 Windows 软件可以实现这样的实时时钟同步并与 ping 补偿或其他类型的精度提高?

答案1

非常有趣的问题,所以我对几个来源进行了一些挖掘。

文章第二部分:系统时间的调整作者:Arno Lentfer,2012 年(PDF),包含许多测量值,并指出:

事实证明,Windows 与网络时间参考的同步并不十分准确。特别是,Windows 版本 VISTA 和 7 似乎出于某些未知原因而失去了一些功能。不幸的是,关于这个问题的信息并不多,现有的少量信息基本上表明,Windows 时间同步的准确度不应超过几秒钟,并且 SetSystemTimeAdjustment 的行为可能存在与 dwTimeAdjustment 值含义相关的问题。现在只有 Windows 8 克服了这些缺点,其系统时间调整的性能与 Windows XP 相同。

文章指出,系统时钟中存在一些小的内置误差,通常无法保持准确的时间。分析表明,使用所检查的硬件,系统时间可能比实际时钟快 0.0448 ms/s。

微软文章 支持边界以配置 Windows 时间服务以实现高精度环境的结论是,在严格控制的环境中,使用 Windows 10 和 Windows Server 2016,您所能期望的最佳精度是 1 毫秒。微软的文档详细说明了 1 秒、50 毫秒和 1 毫秒精度的要求,而较旧的操作系统则很难保持在几秒之内。

相比之下,Domain Time II 实现了亚毫秒级的可证明精度,并且在使用 IEEE 1588-2008 精确时间协议 (PTP) 时,可以实现低两位数微秒级的精度。

微软文章概述了给定精度的要求:

目标精度:1秒(1s)要求

  • 目标系统必须运行 Windows 10、Windows Server 2016。
  • 目标系统必须从高精度 NTP 时间源同步时间
  • NTP 层次结构中的 Windows 系统必须正确配置
  • 目标和源之间的累计单向网络延迟不得超过 100 毫秒。

目标精度:50毫秒要求

  • 目标计算机与其时间源之间的网络延迟必须优于 5ms。
  • 目标系统与高精度时间源之间的距离不得超过第 5 层
  • 目标系统与高精度时间源之间的网络跳数必须在 6 个或更少以内
  • 所有层的一天平均 CPU 利用率不得超过 90%
  • 对于虚拟化系统,主机一天的平均 CPU 利用率不得超过 90%

注意:w32tm /query /status从命令行运行即可查看层。

目标精度:1毫秒要求

  • 目标计算机与时间源之间的网络延迟必须小于 0.1 毫秒
  • 目标系统与高精度时间源之间的距离不得超过第 5 层
  • 目标系统与高精度时间源之间的网络跳数必须在 4 个或更少以内
  • 每个层的一天平均 CPU 利用率不得超过 80%
  • 对于虚拟化系统,主机一天的平均 CPU 利用率不得超过 80%

如果你想知道什么是层,那么重要的是要意识到 NTP 是一个分层的、半分层的时钟级别系统。下图来自文章 网络时间协议(NTP)有多准确?作者:Dave Gault(PDF):

NTP 层次结构

文章还列出了可能对时间显示质量产生不利影响的因素:

  • 互联网连接的速度(延迟)。
  • 选择用于同步的时间服务器的层数。
  • 与服务器的信号距离(包括往返于轨道卫星的距离)。
  • 所用软件算法的质量和复杂性。
    • 它是否使用多个服务器?
    • 它是否计算往返延迟?
    • 它能弥补系统性偏差吗?
    • 它是否报告同步的准确性?

这比我预期的要长。但要回答你的问题:

与 Windows 7 的调整日期/时间 > Internet 时间 > 更改设置 > 立即更新... 进行同步的记录精度是多少?

这取决于上述目标精度的哪些要求适用于您的安装。如果上述要求均不适用,您的时间可能与实际时间最多相差 2 秒。NTP 时间服务器也可能存在误差,具体取决于其层。还请注意,使用计算机的实时时钟时,您将遇到恒定的时间漂移​​,您可能能够测量(或可从制造商处获得)。

更具体地说,它是否补偿时间服务器的 ping?

答案是否定的。这取决于你自己的测量,记住 ping 时间可能不会保持不变。

结论:如果您需要比互联网时间服务器提供的更高的时间精度,则需要获取并使用专门的时钟设备。

有趣的阅​​读是算法交易文章 Windows 上的精确计时,解释了微软如何改进其内部计时功能以及系统时钟的精度:

图像

设置或检查计算机时间的有用工具

如果你希望通过互联网将你的计算机时间与低层服务器同步,你可以使用免费产品 维度 4

Dimension 4 使用一种称为 SNTP 的低级互联网协议来连接专用互联网时间服务器,这些服务器在过去 20 多年中一直保持着互联网其余部分的准时性。这些时间服务器通常可以直接访问自己的时间源,或者直接连接到其他拥有该权限的互联网时间服务器。

在您指定的时间间隔内,Dimension 4 会连接到其中一个 Internet 时间服务器,您可以从直接内置于 Dimension 4 中的详尽列表中进行选择。然后,时间服务器将正确的时间发送回您的计算机,Dimension 4使用复杂的算法来正确调整计算机时钟,使其与实际时间相差几毫秒

您也可以根据网站验证您的计算机时钟 时间是

图像

答案2

这是使用 Python 进行时间设置的尝试,根据 NTP 服务器,补偿时间服务器和我之间的数据包的行程时间(见时钟同步算法):

NTPSERVER, PORT = 'pool.ntp.org', 123

from contextlib import closing
from socket import socket, AF_INET, SOCK_DGRAM, SOCK_STREAM
import struct, time, sys, datetime
import win32api  # pip install pywin32

t0 = time.time()
with closing(socket(AF_INET, SOCK_DGRAM)) as s:
    s.sendto('\x23' + 47 * '\0', (NTPSERVER, PORT))   # see https://stackoverflow.com/a/26938508
    msg, address = s.recvfrom(1024)                   # and https://stackoverflow.com/a/33436061
t3 = time.time()

unpacked = struct.unpack("!12I", msg[0:struct.calcsize("!12I")])  # ! => network (= big-endian), 12 => returns 12-tuple, I => unsigned int

t1 = unpacked[8] + float(unpacked[9]) / 2**32 - 2208988800L     # see https://tools.ietf.org/html/rfc5905#page-19
t2 = unpacked[10] + float(unpacked[11]) / 2**32 - 2208988800L   # and https://tools.ietf.org/html/rfc5905#page-13

offset = ((t1 - t0) + (t2 - t3)) / 2    # https://en.wikipedia.org/wiki/Network_Time_Protocol#Clock_synchronization_algorithm
roundtrip = (t3 -  t0) - (t2 - t1)

print "Local computer time (t0)                               %.3f" % t0
print "NTP server time (t1, receive timestamp)                %.3f" % t1 
print "NTP server time (t2, transmit timestamp)               %.3f" % t2
print "Local computer time (t3)                               %.3f" % t3
print "Offset                                                 %.1f ms" % (offset * 1000)
print "Local -> NTP server -> local roundtrip time            %.1f ms" % (roundtrip * 1000)
print "New local computer time                                %.3f" % (t3 + offset)

dt = datetime.datetime.utcfromtimestamp(t3 + offset)
win32api.SetSystemTime(dt.year, dt.month, dt.isocalendar()[2], dt.day, dt.hour, dt.minute, dt.second, dt.microsecond / 1000)

输出示例:

Local computer time (t0)                               1528290913.275
NTP server time (t1, receive timestamp)                1528290913.297
NTP server time (t2, transmit timestamp)               1528290913.297
Local computer time (t3)                               1528290913.340
Offset                                                 -10.5 ms
Local -> NTP server -> local roundtrip time            65.0 ms
New local computer time                                1528290913.330

笔记:

  • 我们本可以使用ntplib但是这里的好处是我们了解了它的内部工作原理,而且代码也不长!

  • 在这种情况下t1 == t2(在我的测试中,情况总是如此),那么t3 + offset = t1 + (t3 - t0)/2,并且这个计算给出的结果与这个答案的完全相同先前的编辑 tcompensated = t + (now-start) / 2

  • ((t1 - t0) + (t2 - t3)) / 2 真的给出本地时钟和 NTP 服务器时钟之间的偏移量。实际上,我们将trip数据包从本地计算机到 NTP 服务器的单程行程时间称为。然后t1 = t0 + offset + tript3 = t2 - offset + trip。然后((t1 - t0) + (t2 - t3)) / 2 = (offset + trip + offset - trip) / 2 = offset

相关内容