24

通常、実時間はシステム RTC によって提供されます。これはほとんどの場合、ミリ秒の範囲までの時間を提供するだけで、通常は 10 ~ 20 ミリ秒の粒度です。ただし、 gettimeofday()の解像度/粒度は、多くの場合、数マイクロ秒の範囲であると報告されています。マイクロ秒の粒度は別のソースから取得する必要があると思います。

gettimeofday() のマイクロ秒の解像度/粒度はどのように達成されますか?

ミリ秒までの部分が RTC から取得され、ミリ秒が別のハードウェアから取得される場合、2 つのソースの位相に関する問題が発生します。2つのソースはsynchronized何らかの方法である必要があります。

これら 2 つのソース間の同期/位相はどのように達成されますか?

編集: amdn が提供するリンク、特に次のIntelリンクで読んだことから、ここに質問を追加します。

gettimeofday()マイクロ秒領域で解像度/粒度を提供しますか?


編集 2: amdns の回答をいくつかの読み取り結果で要約します。

Linux は、起動時にリアルタイム クロック (RTC) のみを使用して、Timestampcounter (TSC) などの高解像度カウンターと同期します。起動後、gettimeofday()TSC 値とこのカウンターの頻度に完全に基づく時間が返されます。TSC の初期値はfrequency、システム時刻を外部時刻ソースと比較することによって修正/較正されます。調整は、adjtimex()関数によって実行/構成されます。カーネルはフェーズ ロック ループを操作して、時間の結果が単調で一貫していることを確認します。

このようにしgettimeofday()て、マイクロ秒の分解能があると言えます。最新の Timestampcounter が GHz 領域で実行されていることを考慮すると、取得可能な解像度はナノ秒領域になる可能性があります。したがって、この意味のあるコメント

/**
407  * do_gettimeofday - Returns the time of day in a timeval
408  * @tv:         pointer to the timeval to be set
409  *
410  * NOTE: Users should be converted to using getnstimeofday()
411  */

Linux/kernel/time/timekeeping.cにあります。これは、後の時点でさらに高い解像度の機能が利用可能になる可能性があることを示唆しています。現在getnstimeofday()、カーネル空間でのみ利用可能です。

ただし、これを正しく行うために関連するすべてのコードを調べると、不確実性に関するかなりの数のコメントが表示されます。マイクロ秒の分解能が得られる可能性があります。この関数gettimeofday()は、マイクロ秒領域の粒度を示すことさえあります。ただしdrift、TSC 周波数を正確に補正できないため、その精度については深刻な問題があります。また、Linux 内でこの問題を処理するコードが複雑であることは、実際にはそれを正しく行うのが難しすぎることを示唆しています。これは特に、Linux が実行されるはずの膨大な数のハードウェア プラットフォームだけが原因ではありません。

結果: マイクロ秒の粒度で単調な時間を返しますが、それが提供する時間は、他の時間ソースとgettimeofday()位相が一致することはほとんどありません。one microsecond

4

2 に答える 2

19

gettimeofday() のマイクロ秒の解像度/粒度はどのように達成されますか?

Linux はさまざまなハードウェア プラットフォームで実行されるため、仕様は異なります。最新の x86 プラットフォームでは、Linux はとしても知られるタイム スタンプ カウンターTSCを使用します。これは、133.33 MHz で動作する水晶発振器の倍数によって駆動されます。水晶発振器はプロセッサに基準クロックを提供し、プロセッサはそれをいくつかの倍数で乗算します。たとえば、2.93 GHz プロセッサでは、倍数は 22 です。これTSCは、プロセッサが停止したときに実装がカウンターを停止するため、歴史的に信頼できない時間のソースでした。または、プロセッサーが乗数をシフトしてパフォーマンス状態を変更したり、熱くなったときにスロットルを下げたりしたため、倍数が一定ではなかったためです。最新の x86 プロセッサーは、TSCつまり、一定で、不変で、ノンストップです。これらのプロセッサでTSCは、 は優れた高解像度クロックであり、Linux カーネルは起動時に初期のおおよその周波数を決定します。はTSC、gettimeofday() システム コールにマイクロ秒の精度を提供し、clock_gettime() システム コールにナノ秒の精度を提供します。

この同期はどのように行われますか?

最初の質問は、Linux クロックがどのように高解像度を提供するかについてでした。この 2 番目の質問は同期に関するもので、これは精度と精度の違いです。ほとんどのシステムには、システムの電源がオフになっているときに時刻を保持するために、バッテリによってバックアップされるクロックがあります。ご想像のとおり、この時計の正確性や精度は高くありませんが、システムが起動すると「大まかな」時刻が取得されます。精度を得るために、ほとんどのシステムはオプションのコンポーネントを使用して、ネットワーク上の外部ソースから時間を取得します。2つの一般的なものは

  1. ネットワーク タイム プロトコル
  2. 高精度時間プロトコル

これらのプロトコルは、ネットワーク上のマスター クロック (またはアトミック クロックをソースとするクロック層) を定義し、ネットワーク レイテンシを測定してマスター クロックからのオフセットを推定します。マスターからのオフセットが決定されると、システムクロックはdisciplinedそれを正確に保つ必要があります。これは、

  1. 時計を進める (比較的大きく、急激で、まれな時間調整)、または
  2. Slewingクロック (一定の時間内に周波数をゆっくりと増加または減少させることにより、クロック周波数を調整する必要がある量として定義されます)

カーネルは、adjtimex システム コールを提供して、クロックの規律を可能にします。最新のインテル マルチコア プロセッサがコア間で TSC の同期を維持する方法の詳細については、特にマルチコア マルチプロセッサ環境での CPU TSC フェッチ操作を参照してください。

クロック調整に関連するカーネル ソース ファイルは、kernel/time.cおよびkernel/time/timekeeping.cです。

于 2012-11-05T11:57:13.090 に答える
0

Linuxが起動すると、ハードウェアクロックを使用してソフトウェアクロックが初期化されます。Linuxが時計の時間を追跡する方法HOWTOの章を参照してください。

于 2012-11-05T11:03:29.233 に答える