2016-01-01 3 views
1

Следующий абзац спутал мне:QueryPerformanceCounter или GetSystemTimePreciseAsFileTime При использовании SNTP?

Из статьи: Acquiring high-resolution time stamps

Когда вам нужна метка времени с разрешением 1 мкс или лучше и вам не нужно метки времени для синхронизации на внешнюю ссылку , выберите QueryPerformanceCounter, KeQueryPerformanceCounter, или KeQueryInterruptTimePrecise. Когда вам нужны , необходимо время, прошедшее с UTC, с разрешением 1 микросекунды или выше, выберите GetSystemTimePreciseAsFileTime или KeQuerySystemTimePrecise.

Что означает фраза «для синхронизации с внешним опорным сигналом времени» именно здесь означает? Что я узнаю это:

  1. Если ваш компьютер не подключен к GPS (через последовательный порт или SNTP) используют QueryPerformanceCounter.
  2. Если компьютер подключен, используйте GetSystemTimePreciseAsFileTime.

Правильно ли это предположение?

ответ

0

QueryPerformanceCounter() сообщит вам точно, сколько времени прошло с момента предыдущего вызова QueryPerformanceCounter(). Это очень полезно как секундомер, чтобы рассчитать прошедшее время.

GetSystemTimePreciseAsFileTime() говорит вам, немного менее точно, текущее время календаря/даты, основанное на некоторой ссылке (например, системные часы). Например, вы можете использовать его для печати «12 декабря 14:17:51 2016».

Как таковое, ваше предположение неверно. Если вы подключаетесь к GPS или сетевому источнику времени, это не изменится, если вы звоните одному или другому. Потребности вашего приложения будут определять, к чему вы должны звонить.

В основном вам нужно знать, в какое время (GSTPAFT) или сколько времени (QPC)?

2

«текущий» время, возвращаемое различными функциями Windows, не всегда подсчитывается со скоростью 60 секунд каждый раз.

Иногда Windows намеренно имеет часы происходит немного медленнее, или немного быстрее:

  • Если ваши часы PC в настоящее время за текущий правильное время: работать чуть быстрее догнать
  • Если ваши часы PC в настоящее время опережает текущее Corret время: работать немного медленнее , чтобы позволить правильное время догнать этот

Он делает это вместо того, чтобы иметь ваши часы внезапно JUMP, и теперь ваши лог-файлы имеют временные аномалии.

Вы можете использовать GetSystemTimeAdjustment, чтобы увидеть, если Windows, в настоящее время отсчитывают ваши часы быстрее или медленнее или по номинальной ставке. Например, на моем компьютере прямо сейчас:

  • System Time Установка: Disabled
  • Добавление номинальной 15,6250 мс каждое обновление

Но если ваши часы слишком далеко от правильного время, Windows будет BONK ваше время в нужное время.

Время может работать быстро, медленно, прыгать вперед, прыгать назад. QueryPerformanceCounter не

Так раз возвращаемый:

| Function      | Return type  | Resolution | Timezone | 
|--------------------------------|-------------------|------------|----------| 
| GetLocalTime     | SYSTEM_TIME (1ms) | ~10-15 ms | Local | 
| GetSystemTime     | SYSTEM_TIME (1ms) | ~10-15 ms | UTC  | 
| GetSystemTimeAsFileTime  | FILE_TIME (0.1us) | ~10-15 ms | UTC  | 
| GetSystemTimeAsPreciseFileTime | FILE_TIME (0.1us) | 0.1 us  | UTC  | 

Может все быстро бегать, медленно или прыгать, как ваши часы проскакивает. Пока QueryPerformanceCounter никогда не ускоряется и не замедляется. Он всегда рассчитывается с точностью до 60 с/мин.

| Function      | Return type  | Resolution | Timezone | 
|--------------------------------|-------------------|------------|----------| 
| GetLocalTime     | SYSTEM_TIME (1ms) | ~10-15 ms | Local | 
| GetSystemTime     | SYSTEM_TIME (1ms) | ~10-15 ms | UTC  | 
| GetSystemTimeAsFileTime  | FILE_TIME (0.1us) | ~10-15 ms | UTC  | 
| GetSystemTimeAsPreciseFileTime | FILE_TIME (0.1us) | 0.1 us  | UTC  | 
|        |     |   |   | 
| GetTickCount     | Int32 (1ms)  | ~10-15 ms | n/a  | 
| GetTickCount64     | Int64 (1ms)  | ~10-15 ms | n/a  | 
| QueryPerformanceCounter  | Int64 (ticks)  | 0.1 us  | n/a  | 

Так что вы заботитесь о

Пока часы вашего компьютера не в настоящее время проходят SystemTimeAdjustment истекшее интервалы измеряются:

  • GetSytemTimeAsPreciseFileTime
  • QueryPerformanceCounter

будет оба:

  • быть синхронизированы
  • быть в пределах нескольких десятых доли микросекунды каждого другого
  • имеет конечное разрешение 100 нса (0.1 us)

Для точного измерения времени это две функции, которые вы должны использовать. Вопрос, какой из них вы заботитесь для выполнения этой задачи:

  • GetSystemTimeAsPreciseFileTime: высокое измерение разрешение «сейчас»

    • хорошо для файлов журнала
    • временных меток событий
    • синхронизирован к UTC для межмашинного соглашения «сейчас»
  • QueryPerformanceCounter: высокое измерение разрешения "истекшее время"

    • хорошо для стендовой маркировки
    • измерения длительности процессов

бонуса болтовня

Это должно быть отметил, что структура SYSTEM_TIME возвращается GetLocalTime и GetSystemTime по своей сути ограничены точностью в миллисекундах. Там нет никакого способа для GetSystemTime, чтобы дать вам разрешение суб-миллисекунды, просто потому, что тип возвращаемого значения не имеет места, чтобы дать вам микросекунд:

struct SYSTEMTIME { 
    WORD wYear; 
    WORD wMonth; 
    WORD wDay; 
    WORD wHour; 
    WORD wMinute; 
    WORD wSecond; 
    WORD wMilliseconds; //<---- that's the limit 
} 

Вы должны использовать только SYSTEM_TIME, когда вы хотите Windows, чтобы сломать время для вас вниз, лет, месяцев, дней, часов, минут, секунд. С другой стороны, структура FILE_TIME является максимальной точностью 100ns (0,1 us).

Точные временные функции

В языке я использую, мы используем DateTime, что является плавающей точкой а Double точности, где:

  • целой часть представляет собой количество дней с момента 12/30/1899
  • дробная часть представляет собой часть 24-часовой день

Это схема даты и времени используется по COM, OLE, Delphi, VB, Excel, Lotus 123; и аналогично схеме datetime, используемой SQL Server (хотя они используют 1/1/1900, а не 12/30/1899)

DateTime UtcNowPrecise() 
{ 
    const UInt64 OA_ZERO_TICKS = 94353120000000000; //12/30/1899 12:00am in ticks 
    const UInt64 TICKS_PER_DAY = 864000000000;  //ticks per day 

    FILE_TIME ft; 
    GetSystemTimePreciseAsFileTime(out ft); 

    ULARGE_INTEGER dt; //needed to avoid alignment faults 
    dt.LowPart = ft.dwLowDateTime; 
    dt.HighPart = ft.dwHighDateTime; 

    return (dt.QuadPart - OA_ZERO_TICKS)/TICKS_PER_DAY; 
} 

DateTime NowPrecise() 
{ 
    const UInt64 OA_ZERO_TICKS = 94353120000000000; //12/30/1899 12:00am in ticks 
    const UInt64 TICKS_PER_DAY = 864000000000;  //ticks per day 

    FILE_TIME ft; 
    GetSystemTimePreciseAsFileTime(out ft); 

    //Convert from UTC to local 
    FILE_TIME ftLocal; 
    if (!FileTimeToLocalFileTime(ft, ref ftLocal)) 
     RaiseLastNativeError(); 

    ULARGE_INTEGER dt; //needed to avoid alignment faults 
    dt.LowPart = ftLocal.dwLowDateTime; 
    dt.HighPart = ftLocal.dwHighDateTime; 

    return (dt.QuadPart - OA_ZERO_TICKS)/TICKS_PER_DAY; 
} 
Смежные вопросы