[編集] 古い回答を記憶から書き留めたので、参照を含めて大幅に書き直しました。
短い答え:いいえ 現在、x86/x64 プラットフォームでありふれたオペレーティング システムでミリ秒単位の精度を実現することは不可能です。
免責事項 私は普通のシステム管理者であり、コンピューターの通常のシステム管理者ビューを持っているため、これは素人の回答です。カーネル開発者やハードウェア アーキテクトの中には、計時に関するプロ レベルの知識が含まれている可能性があります。
長い答え:
どこかから始めなければなりません。これをトップダウンで行います。アプリケーションがオシレーターに向かって下に移動するところから始めます。
1 つ目の問題は、1 台のコンピューターで時間管理を行うのではなく、環境全体で時間管理に同意するように管理することです。何の計時?今日のコンピューターで時間を計るには、いくつかの方法があることがわかりました。最もよく目にするのはシステム時間です (画面の隅の 1 つに表示されます)。数段落下の単純で複雑な事柄のふりをすることから始めましょう。
システム時刻が正確であり、すべてのコンピューターで均一であることを望んでいます。信頼できる情報源から非常に詳細なレベルで情報を伝達し、どのような要件であっても要件を満たす方法が必要です。
要件を 1 ミリ秒の許容レベルにしましょう。つまり、環境内で時間が 1 ミリ秒ずれたり、重要な目標を達成できなかったりする可能性があります。具体的に、Microsoft が私たちのためにできることを見てみましょう。
NT などの廃止されたものを除いて、Windows ネイティブは、単純化された ntp (XP/2003 以降のドメインに参加しているコンピューター) または単純化された sntp (Win2k 以降のドメインに参加していないコンピューター) に基づいてタイムキーピングを実行します。 . Microsoft は、タイムキーピングの実装を行う際に 2 つの目標を設定しましたが、どちらにも望ましいレベルの精度は含まれていません。
「ネットワーク上のノード間の W32Time サービスの正確性は保証もサポートもしていません。W32Time サービスは、時間に敏感なアプリケーションのニーズを満たすフル機能の NTP ソリューションではありません。W32Time サービスは主に設計されています。次のことを行います:
- Kerberos バージョン 5 認証プロトコルを機能させる
- クライアント コンピューターに緩やかな同期時間を提供する
W32Time サービスは、同期時間を 1 ~ 2 秒の範囲に確実に維持することはできません。このような許容範囲は、W32Time サービスの設計仕様の範囲外です。"
わかった。サービス スタックを複数のコンピューターで実行していて、イベント相関のタイムキーピング許容レベルが 1 ミリ秒に近づいていると仮定すると、これは非常に残念です。サービス スタックに 2 台のコンピューターが含まれている場合、実際には Windows ネイティブのタイムキーピングをまったく使用できません。ただし、ここで、Windows ネイティブの時間管理に関する重要なポイントを 1 つか 2 つ強調し、詳細なドキュメントをいくつか含めてみましょう。
AD がある場合、特定のドメインの時刻が PDC エミュレーターの役割から同期されることを確認してください。したがって、ドメインに正しい時刻をもたらすには、PDC エミュレーターの役割を実行しているドメイン コントローラーを介する必要があります。マルチドメイン フォレストの場合、これはフォレスト ルート ドメインの PDC エミュレーターに変換されます。そこから、時間は主にサブドメインの PDC エミュレーターと各ドメイン メンバーにファンアウト形式で分散されます (いくつかの注意事項があります)。このプロセスは、ここに文書化されています。さらに詳しい情報はこちら
わかった。何ができるでしょうか?
まず、環境全体で時刻を同期するためのより正確な方法が必要です。 Linux ntpd または Windows 用 ntpd を実行できないと仮定すると、Tardis と呼ばれるシェアウェア クライアントを調べることができますが、試すべきものが他にもたくさんあると思われます。
不可解な歴史的理由により、ネットワーク全体をそこから同期するしかありませんでした。現在、外部の原子時計から時間を取得する専用の Linux ntpd に置き換えられて大喜びしていますが、Tardis はその場で見事に私たちを救ってくれました。 ただし、Windows ネイティブよりも高い精度を達成するのに役立つかどうかはわかりません.
しかし、この時点から、完全な代替ネットワーク時刻同期を実装する方法を見つけたと仮定しましょう。その固有の狡猾さにより、1ミリ秒未満の許容レベルの能力があります。 AD がネットワークを介して拡散する時間をどのように予測するかを強制するために、これを配置しました。
これは、オペレーティング システムとマイクロサービスから 1 ミリ秒に近い精度で正確な診断を取得できるということですか?
x86/x64 アーキテクチャのオペレーティング システムがプロセッサ時間をスケジュールする方法を見てみましょう。
彼らは、考古学的物質に富む多面的な獣である割り込みを使用します。ただし、割り込みを必要とするのはオペレーティング システムだけではありません。ハードウェアも割り込みを望んでおり、それを行う手段があります! (こんにちは、キーボード) オペレーティング システムも一緒にプレイします。
ここが複雑になるところです。単純化しすぎて解決します。質問?私は身を隠し、カバーし、この主題に関する絶対に優れた論文を紹介します。 (Windows プラットフォームで数ミリ秒を探しているなら、本当に読むべきです..) Win8.1/Win2012r2 の更新バージョンが開発中であると報告されていますが、リリース日はまだ明らかにされていません.
よし、割り込む。 OS で何かが発生するたびに、割り込みが後続のアクションをトリガーします。アクションは、カーネルからフェッチされた一連の命令であり、さまざまな方法で実行できます。要するに、ハードウェア アーキテクチャとカーネルの割り込み処理に応じて多かれ少なかれ正確に判断できる割り込みの発生にもかかわらず、実行の後続の部分が発生する正確な時刻は通常はわかりません。特定の命令セットが、割り込み後の早い段階で実行されるか、遅れて実行される可能性があります。予測可能なシーケンスで実行されるかどうかに関係なく、バグのあるハードウェアまたは認識が困難なレイテンシに影響する不適切に記述されたドライバーの犠牲になる可能性があります。ほとんどの場合、単に知らないだけです。後続のログ ファイルに表示されるミリ秒レベルのタイムスタンプ - 非常に正確ですが、イベントがいつ発生したかについては正確ですか?
計時割り込みで一旦停止します。割り込みには優先レベルがあり、最も低いレベルはユーザー アプリケーション (標準サービスなど) がプロセッサ時間を取得する場所です。他の (より高い) レベルは、ハードウェアおよびカーネル作業用に予約されています。最低レベルより上のレベルの割り込みが到着した場合、システムは優先順位の低い割り込みがキューに存在しないふりをします (優先順位の高い割り込みが処理されるまで)。実行中の通常のアプリケーションとサービスは、この方法でプロセッサ時間の最後になります。対照的に、クロック割り込みにはほぼ最高の優先度が与えられます。時間の更新は、ほぼ常にシステム内で行われます。これは、すべてがどのように機能するかを犯罪的に単純化しすぎていますが、この回答の目的を果たしています。
更新時間は、実際には次の 2 つのタスクで構成されます:
-
システム時刻の更新 / ウォール クロックとも呼ばれる / 誰かに今何時かと尋ねられたときに私が言うこと / ntp が近くのシステムと相対的に少し前後すること。
-
コード実行の継続時間を測定する場合などに使用される、ティック カウントの更新。
しかし、ウォール タイムであろうとティック カウントであろうと、システムはどこから時間を取得するのでしょうか?これは、ハードウェア アーキテクチャに大きく依存します。ハードウェアのどこかで 1 つまたは複数のオシレーターが刻んでおり、その刻みは、多かれ少なかれ精度と正確さでウォール タイムとティック カウントを更新するときに、カーネルとの接続のためのいくつかの可能なパスの 1 つを介してインターフェイスにもたらされます。
マルチコア システムでの発振器の配置にはいくつかの設計モデルがありますが、主な違いは同期配置と非同期配置のようです。これらは、正確な計時に対するそれぞれの課題とともに、たとえばここで説明されています。
つまり、同期タイムキーピングには、マルチコアごとに 1 つの基準クロックがあり、その信号がすべてのコアに分配されます。非同期タイムキーピングには、コアごとに 1 つの発振器があります。最新の Intel マルチコア プロセッサ (Haswell) は、「Forwarded Clocking」を備えた「QuickPath Interconnect」と呼ばれるシリアル バスを使用する何らかの形式の同期設計を使用していることに注意してください。データシート。 Forwarded Clocking は、素人 (私) がここで簡単に表面的に理解できるように説明されています。
OK、それで、すべてのナーダリズムが邪魔にならないように (これは、計時が、それに関する多くの生きた歴史を持つ複雑で実際的なタスクであることを示すのに役立ちました)、割り込み処理をさらに詳しく見てみましょう.
オペレーティング システムは、ティックまたはティックレスという 2 つの異なる戦略のいずれかを使用して割り込みを処理します。あなたのシステムはどちらか一方を使用していますが、用語の意味は何ですか?
時を刻むカーネル 一定間隔で割り込みを送信します。 OS は、ティック間隔より細かい分解能で時間を測定することはできません。それでも、1 つまたは複数のアクションの実行に関連する実際の処理には、ティック間隔よりも大きな遅延が含まれる可能性があります。たとえば、サービス間の呼び出しに固有の遅延が比較的多くの時間を消費する可能性がある分散システム (マイクロサービスなど) を考えてみましょう。それでも、すべての命令セットは、OS によって測定される 1 つまたは複数の割り込みに関連付けられます。その分解能は、カーネルのティック時間よりも細かくありません。ティック時間には基本値がありますが、少なくとも Windows では、個々のアプリケーションの要求に応じて減らすことができます。これは、利益だけでなくコストにも関連するアクションであり、かなり細かい部分が含まれています。
いわゆるティックレス カーネル (非常にわかりやすい名前を持っています)は比較的新しい発明です。 tickless カーネルは、刻み時間を可変間隔で設定します (将来的に可能な限り長い期間)。その理由は、電力を節約するという単純な目的で、プロセッサ コアがさまざまなレベルのスリープ状態になることを OS が動的に許可するためです。 「さまざまなレベル」には、命令を全速力で処理する、速度を下げて処理する (つまり、より遅いプロセッサ速度)、またはまったく処理しないことが含まれます。さまざまなコアがさまざまな速度で動作することが許可されており、ティックレス カーネルは、割り込みバッチでそれらを起動する命令をキューに入れるなどの場合でも、プロセッサを可能な限り非アクティブにしようとします。要するに、マルチプロセッサ システム内の異なるコアは、相互に時間のずれが許容されます。もちろん、これは適切な時間管理に大混乱をもたらし、これまでのところ、新しい省電力プロセッサ アーキテクチャと効率的な省電力を可能にするティックレス カーネルでは解決されていない問題です。これを、実際の作業を受け取っているかどうかに関係なく、すべてのプロセッサコアを継続的にウェイクアップするティックカーネル (静的ティック間隔) と比較してください。時間管理にはある程度の不正確さがありますが、ティックレスカーネルと比較して比較的信頼できる程度です.
標準の Windows ティック タイム (システム解像度) は、Windows 8/2012 までは 15.6 ミリ秒であり、デフォルトの動作はティックレスです (ただし、ティック カーネルに戻すことができます)。 Linux のデフォルトのティック タイムは、カーネルのコンパイルに依存すると思いますが、このニッチは私の経験 (およびこれも) の範囲をはるかに超えているため、依存しているかどうかを再確認することをお勧めします。 Linux カーネルは 2.6.21 から tickless でコンパイルされていると信じており、tickle の動作を最適化するさまざまなフラグを使用してコンパイルされている可能性があります (no_hz のいくつかのバリアントしか思い浮かびません)。
ベアメタルシステムについては以上です。仮想システムでは、VM とハイパーバイザーが異なる方法で競合するため、正確な時間管理が非常に困難になるため、状況はさらに悪化します。 VMware の概要と RHEL KVM の概要を次に示します。同じことが分散システムにも当てはまります。クラウド システムは、実際のハイパーバイザーやハードウェアに近づくことさえできないため、さらに困難です。
結論として、システムから正確な時間を取得することは、多層的な問題です。高レベルの観点からボトムアップすると、次のことを解決する必要があります:ハードウェアとカーネルの間の内部時間同期、割り込み処理、および仮想環境での不正確な時間の場合に必要な命令の実行の遅延2 番目の OS レイヤーのカプセル化により、分散システム間の時間の同期が行われます。
したがって、コンピューティングの歴史のこの時点では、x86/x64 アーキテクチャからミリ秒レベルの精度を得ることはできません。少なくとも、ありきたりのオペレーティング システムを使用しなければです。
しかし、どこまで近づくことができるでしょうか?わかりませんが、システムによって大きく異なるはずです。自分自身の特定のシステムの不正確さを把握することは、困難な作業です。 Intel がどのようにコードのベンチマークを行うべきかを提案する方法を見るだけで、私がたまたま管理しているような通常のシステムが、この観点からは非常に制御不能であることがわかります。
「すべての電力最適化、Intel ハイパースレッディング テクノロジ、周波数スケーリング、およびターボ モード機能がオフになっている」 重要なシステムでは、C のコード ラッパーをいじったり、その後の答えを得るために長期的なテストを実行したりすることはほとんどありません。私は彼らを生かし続け、あまり邪魔をせずにできるだけ多くのことを学ぼうとしています.タイムスタンプに感謝します。あなたを完全に信頼できないことはわかっていますが、数秒も遅れていないことはわかっています。実際のミリ秒の精度が重要になると、1 回の測定では不十分で、パターンを検証するためにさらに多くの測定が必要になります。他に何ができますか?
最後に、リアルタイム OS の人々が割り込みレイテンシをどのように考えているかを見るのは興味深いことです。非常にエキサイティングな時間同期の代替案も進行中であり、かなりの興味深い統計、方法論、およびホワイトペーパーが公開されています。将来のハードウェア アーキテクチャとカーネルの開発をそれに加えれば、数年後には、この計時精度の問題は、もはやそのような問題ではなくなるかもしれません。期待できるかもしれません。