2

の値を出力する緊密にループされたテスト アプリケーションではDateTime.UtcNow.Ticks、値が約 1 時間ごとに驚くべき量ジャンプすることに気付きました。次のサンプル データをよく見てください。

1:52:14.312 PM - 633614215343125000
1:52:14.359 PM - 633614215343593750
1:52:14.421 PM - 633614215344218750
1:52:14.468 PM - 633614215344687500
1:52:14.515 PM - 633614215998593750 <-- WAY different

デルタは 653906250 ティック (65.390 秒) です。私が思いつく唯一の理由は、Windows タイム サービスが私の足元で何らかの同期を行っているということです。

  • これを確認できる専門家はいますか?
  • 約1時間で1分ほどドリフトするのは私にはかなり悪いように思えますが、そうですか?
4

5 に答える 5

2

実際には、このループでいくつかのテストを実行するだけです:

static DateTime past = DateTime.UtcNow;
    static void PrintTime()
    {
        while (stopLoop == 0)
        {
            DateTime now = DateTime.UtcNow;
            Console.WriteLine("{0} - {1} d: {2}", now, now.Ticks, now - past);
            Program.past = now;
            Thread.Sleep(2000);
        }
    }

呼び出しの間にシステムのクロック時間を変更すると、それに応じてデルタがジャンプします。したがって、時刻同期を実行している場合、またはシステム時刻に影響を与えるその他のプロセスがある場合は、それが出力に反映されます。

于 2008-11-04T20:42:07.877 に答える
1

ええと...

この時間に何らかのブロック システム コール (Console.WriteLine など) を呼び出していないことを確認できない場合、この方法で時間を測定するにはどうすればよいでしょうか。

「動作テスト」を行うには、少なくとも次のことを確認する必要があります。

  • あなたのマシンでは他に何も実行されていません
  • プロセス/スレッドの優先度が High などに設定されている
  • Call NO system call... 計算タスクのみを実行
  • スレッド アフィニティを特定の CPU に設定して、CPU 間で切り替えられないようにする

それを行ったとしても、OS は時々 (たとえば、Windows デュアルコア デスクトップ OS では 15 ミリ秒) スレッドを先取りします....そして、UTC 時間でそのような「ジャンプ」を確実に見ることができます-スタンプ。

実質的なカーネル作業を行わずに、ユーザー空間からカーネル空間に (プリエンプション/システム コール中に) 行って戻るだけで、約 1000 CPU サイクルが必要になります...

プロセスが(ブロッキングIOを呼び出すことによって)待機状態になると、さらに悪化する可能性があります...

だから私は本当にあなたの「テスト」を理解していません。IMOこれは完全に正常です。

于 2008-11-05T12:46:40.160 に答える
0

Esteban は正しいです。システム クロックが変更されると、連続するポーリング間のデルタ タイムが変更されます。Windows タイム サービスはこれらの変更を 1 時間ごとに行いますか? 1 時間以内に 1 分ずれる可能性はありますか?

マシンでこれが起こっているのをキャッチするために、チェック間の変化のデルタを追跡している場合は、デルタの異常に高い変化に条件付きブレークポイントを設定できます。

long delta = 0;
long ticks = 0;
long lastTicks = DateTime.UtcNow.Ticks;
while (true)
{
    ticks = DateTime.UtcNow.Ticks;
    delta = ticks - lastTicks;
    lastTicks = ticks;
    // Conditional breakpoint: delta > 100000000 Is True
    Console.WriteLine("{0} - {1}", ticks, delta);
}
于 2008-11-04T20:55:28.863 に答える
0

このデータをどのように生成したかを示すコードを投稿できますか? また、これを実行しているマシンに関する詳細を提供してください。

以下を使用すると、あなたが得ているものが得られません。

        for (int i = 0; i < 10; i++)
        {

            Console.WriteLine(DateTime.Now.ToLongTimeString().ToString() + " - " + DateTime.UtcNow.Ticks.ToString());

            Thread.Sleep(10);
        }
于 2008-11-04T20:16:48.910 に答える
0

元の出力は DebugView でキャッチされました。私のマネージ アプリケーションは、ap/invoke OutputDebugString 呼び出しを作成し、Thread.Sleep(1) も呼び出したスレッドのタイトなループから DateTime.UtcNow.Ticks を出力していました。

\\JLECOURSXP のシステム情報:
稼働時間: 6 日 6 時間 22 分 53 秒
カーネル バージョン: Microsoft Windows XP、マルチプロセッサ フリー
製品タイプ: プロフェッショナル
製品バージョン: 5.1
サービス パック: 3
カーネルビルド番号: 2600
登録団体:
登録所有者:セットアップ
インストール日: 2007 年 6 月 15 日、午後 3 時 35 分 29 秒
IE バージョン: 7.0000
システム ルート: C:\WINDOWS
プロセッサー: 2
プロセッサ速度: 2.9 GHz
プロセッサの種類: Intel(R) Pentium(R) D CPU
物理メモリ: 3070 MB
ビデオ ドライバ: RADEON 9250 - セカンダリ
于 2008-11-04T21:03:08.503 に答える