アプリケーションの この質問 で説明されているプロジェクトの場合、可能な限り最高のタイムクロック精度が必要です。解決策の1つは、コンピューターの リアルタイムクロック を正確に同期させることです。
Windows 7でシンクロを実行する際の文書化された精度は何ですか?日付/時刻の調整>インターネット時刻>設定の変更>今すぐ更新...?
より具体的には、タイムサーバーのpingを補正しますか?
例:
そうでない場合、ping補正またはその他の種類の精度が向上したリアルタイムクロックシンクロを実行できるWindowsソフトウェアはありますか?
非常に興味深い質問なので、いくつかの情報源を掘り下げました。
記事パート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秒)の要件
目標精度:50ミリ秒の要件
注:コマンドラインからw32tm /query /status
を実行して、階層を確認します。
目標精度:1ミリ秒の要件
何が層であるか疑問に思っている場合、NTPは、クロックのレベルの階層的な半層システムであることを理解することが重要です。次の図は、記事Network Time Protocol(NTP)それはどれくらい正確ですか?Dave Gaultによって( [〜#〜] pdf [〜#〜] ):
この記事には、表示される時間の質に悪影響を与える可能性のある要因もリストされています。
- インターネット接続の速度(待ち時間)。
- 同期用に選択されたタイムサーバーの層。
- サーバーからの信号距離(周回衛星を含む).
- 使用されるソフトウェアアルゴリズムの品質と複雑さ。
- 複数のサーバーを使用していますか?
- 往復遅延を計算しますか?
- 体系的なバイアスを補正しますか?
- 同期の精度について報告しますか?
これは私が意図したよりも長く出てきました。しかし、あなたの質問に答えるには:
Windows 7の日付/時刻の調整>インターネット時刻>設定の変更>今すぐ更新...でシンクロを実行する文書化された精度はどのくらいですか?
これは、上記のターゲット精度の要件のどれがインストールに適用されるかによって異なります。上記の要件のいずれにも該当しない場合は、リアルタイムから最大2秒ずれている可能性があります。 NTPタイムサーバーも、その層によっては不正確な場合があります。コンピュータのリアルタイムクロックを使用すると、一定の時間ドリフトが発生することに注意してください。または製造元から入手できる場合があります)。
より具体的には、タイムサーバーのpingを補正しますか?
答えはいいえだ。 pingの時間が一定ではない可能性があることを覚えておいて、それはあなた次第です。
結論:インターネットタイムサーバーで提供されるよりも高い精度が必要な場合は、専用の時計デバイスを取得して使用する必要があります。
興味深い読み物は、アルゴリズムトレーディングの記事 Windowsでの精密タイムキーピング です。これは、Microsoftが内部タイムキーピング機能をどのように改善し、システムクロックの精度を向上させたかを説明しています。
コンピュータの時刻を設定または確認するための便利なツール
コンピュータの時刻をインターネット経由で低層サーバーと同期させたい場合は、無料の製品 Dimension 4 を使用できます。 =:
Dimension 4は、SNTPと呼ばれる低レベルのインターネットプロトコルを使用して、過去20年以上にわたって残りのWebをオンタイムに維持している特別な目的のインターネットタイムサーバーに接続します。これらのタイムサーバーは、通常、独自のタイムソースに直接アクセスするか、アクセスする他のインターネットタイムサーバーに直接接続します。
指定した間隔で、ディメンション4はこれらのインターネットタイムサーバーの1つに接続します。インターネットタイムサーバーは、ディメンション4に組み込まれた完全なリストから選択できます。次に、タイムサーバーは正しい時間をコンピューターに送信します。ここで、ディメンション4高度なアルゴリズムを使用して、コンピューターのクロックをリアルタイムの数ミリ秒以内に正しく調整します。
コンピュータの時計をウェブサイトに対して確認することもできます time.is :
これは、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
_ 。