web-dev-qa-db-ja.com

Windowsのタイムサーバー同期精度はどのくらいですか? (そしてそれはping時間を補償しますか?)

アプリケーションの この質問 で説明されているプロジェクトの場合、可能な限り最高のタイムクロック精度が必要です。解決策の1つは、コンピューターの リアルタイムクロック を正確に同期させることです。

  1. Windows 7でシンクロを実行する際の文書化された精度は何ですか?日付/時刻の調整>インターネット時刻>設定の変更>今すぐ更新...

  2. より具体的には、タイムサーバーのpingを補正しますか?

    例:

    • タイムサーバーは、パケットが正確に12:00:00.000であると言うためにパケットを送信します
    • 私のコンピュータからタイムサーバーへの平均pingが93msであるとしましょう(平均pingは、たとえば最後の1分間に計算されます)
    • タイムサーバーからのパケットは12:00:00.093に私のコンピューターに到達しますよね?
    • 次に、Windowsは時刻を12:00:00.000ではなく12:00:00.093に設定する必要がありますでしょ?
  3. そうでない場合、ping補正またはその他の種類の精度が向上したリアルタイムクロックシンクロを実行できるWindowsソフトウェアはありますか?

6
Basj

非常に興味深い質問なので、いくつかの情報源を掘り下げました。

記事パートII:2012年のArno Lentferによるシステム時間の調整[〜#〜] pdf [〜#〜] )には、多くの測定値が含まれていますこれは言う:

Windowsのネットワーク時間参照との同期は、あまり正確ではないことが判明しています。特に、WindowsバージョンVistaおよび7では、何らかの理由で機能の一部が失われているようです。残念ながら、この問題に関する情報は多くなく、基本的にはWindowsの時刻同期が数秒よりも正確であるとは期待できないこと、および意味に関してSetSystemTimeAdjustmentの動作に問題が発生する可能性があることを示す情報はほとんどありませんdwTimeAdjustmentの値の。これらの欠点を克服したのはWindows 8だけで、そのシステム時間調整はWindows XPの場合と同じように実行されます。

この記事では、システムクロックに組み込まれている小さなエラーがあり、一般に正確な時刻を保持していないと記載されています。分析の結果、調査したハードウェアでは、システム時間は実際のクロックより0.0448 ms/s長くなる可能性があります。

Microsoftの記事 高精度環境用にWindowsタイムサービスを構成するためのサポート境界 は、厳密に制御された環境でWindows 10とWindows Server 2016を使用して、1ミリ秒が望ましいと結論付けています。 Microsoftのドキュメントでは、1秒、50ミリ秒、1ミリ秒の精度の要件について詳しく説明していますが、古いオペレーティングシステムは数秒以内に留まるのに苦労しています。

対照的に、ドメインタイムIIはサブミリ秒の証明可能な精度を達成し、IEEE 1588-2008プレシジョンタイムプロトコル(PTP)を使用すると、2桁のマイクロ秒の低い精度を達成できます。

Microsoftの記事では、特定の精度の要件について概説しています。

ターゲット精度:1秒(1秒)の要件

  • ターゲットシステムはWindows 10、Windows Server 2016を実行している必要があります。
  • ターゲットシステムは、非常に正確な時刻を同期する必要がありますNTPタイムソース
  • NTP階層のWindowsシステムは正しく構成する必要があります
  • ターゲットとソースの間の累積的な一方向のネットワーク遅延は100ミリ秒を超えてはなりません。

目標精度:50ミリ秒の要件

  • ターゲットコンピュータは、タイムソース間のネットワーク遅延が5msを超える必要があります。
  • ターゲットシステムは、非常に正確なタイムソースからのストラタム5以下でなければなりません。
  • ターゲットシステムは、高精度のタイムソースから6以下のネットワークホップ内にある必要があります。
  • すべての層の1日の平均CPU使用率が90%を超えてはなりません
  • 仮想化システムの場合、ホストの1日の平均CPU使用率は90%を超えてはなりません。

注:コマンドラインからw32tm /query /statusを実行して、階層を確認します。

目標精度:1ミリ秒の要件

  • ターゲットコンピュータのタイムソース間のネットワーク遅延は0.1ミリ秒を超えている必要があります
  • ターゲットシステムは、非常に正確なタイムソースからのストラタム5以下でなければなりません。
  • ターゲットシステムは、高精度のタイムソースから4以下のネットワークホップ内にある必要があります。
  • 各ストラタム全体の1日の平均CPU使用率が80%を超えてはなりません
  • 仮想化システムの場合、ホストの1日の平均CPU使用率は80%を超えてはなりません。

何が層であるか疑問に思っている場合、NTPは、クロックのレベルの階層的な半層システムであることを理解することが重要です。次の図は、記事Network Time Protocol(NTP)それはどれくらい正確ですか?Dave Gaultによって( [〜#〜] pdf [〜#〜] ):

NTP hierarchy

この記事には、表示される時間の質に悪影響を与える可能性のある要因もリストされています。

  • インターネット接続の速度(待ち時間)。
  • 同期用に選択されたタイムサーバーの層。
  • サーバーからの信号距離(周回衛星を含む).
  • 使用されるソフトウェアアルゴリズムの品質と複雑さ。
    • 複数のサーバーを使用していますか?
    • 往復遅延を計算しますか?
    • 体系的なバイアスを補正しますか?
    • 同期の精度について報告しますか?

これは私が意図したよりも長く出てきました。しかし、あなたの質問に答えるには:

Windows 7の日付/時刻の調整>インターネット時刻>設定の変更>今すぐ更新...でシンクロを実行する文書化された精度はどのくらいですか?

これは、上記のターゲット精度の要件のどれがインストールに適用されるかによって異なります。上記の要件のいずれにも該当しない場合は、リアルタイムから最大2秒ずれている可能性があります。 NTPタイムサーバーも、その層によっては不正確な場合があります。コンピュータのリアルタイムクロックを使用すると、一定の時間ドリフトが発生することに注意してください。または製造元から入手できる場合があります)。

より具体的には、タイムサーバーのpingを補正しますか?

答えはいいえだ。 pingの時間が一定ではない可能性があることを覚えておいて、それはあなた次第です。

結論:インターネットタイムサーバーで提供されるよりも高い精度が必要な場合は、専用の時計デバイスを取得して使用する必要があります。

興味深い読み物は、アルゴリズムトレーディングの記事 Windowsでの精密タイムキーピング です。これは、Microsoftが内部タイムキーピング機能をどのように改善し、システムクロックの精度を向上させたかを説明しています。

image

コンピュータの時刻を設定または確認するための便利なツール

コンピュータの時刻をインターネット経由で低層サーバーと同期させたい場合は、無料の製品 Dimension 4 を使用できます。 =:

Dimension 4は、SNTPと呼ばれる低レベルのインターネットプロトコルを使用して、過去20年以上にわたって残りのWebをオンタイムに維持している特別な目的のインターネットタイムサーバーに接続します。これらのタイムサーバーは、通常、独自のタイムソースに直接アクセスするか、アクセスする他のインターネットタイムサーバーに直接接続します。

指定した間隔で、ディメンション4はこれらのインターネットタイムサーバーの1つに接続します。インターネットタイムサーバーは、ディメンション4に組み込まれた完全なリストから選択できます。次に、タイムサーバーは正しい時間をコンピューターに送信します。ここで、ディメンション4高度なアルゴリズムを使用して、コンピューターのクロックをリアルタイムの数ミリ秒以内に正しく調整します

コンピュータの時計をウェブサイトに対して確認することもできます time.is

image

7
harrymc

これは、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_(これは私のテストでは常にtrueでした)の場合はt3 + offset = t1 + (t3 - t0)/2であり、この計算はこの回答の 前の編集tcompensated = t + (now-start) / 2

  • _((t1 - t0) + (t2 - t3)) / 2_reallyは、ローカルクロックとNTPサーバークロックの間のオフセットを提供します。実際に、tripローカルコンピューターからNTPサーバーに送信されるパケットの片道のトリップ時間。次に_t1 = t0 + offset + trip_および_t3 = t2 - offset + trip_。次に_((t1 - t0) + (t2 - t3)) / 2 = (offset + trip + offset - trip) / 2 = offset_ 。

1
Basj