Получение высокоточных меток времени

Windows предоставляет API-интерфейсы, которые можно использовать для получения меток времени с высоким разрешением или измерения интервалов времени. Основным API для машинного кода является QueryPerformanceCounter (QPC). Для драйверов устройств API в режиме ядра используется KeQueryPerformanceCounter. Для управляемого кода класс System.Diagnostics.Stopwatch использует QPC в качестве точной базы времени.

QPC не зависит от внешних ссылок на время и не синхронизируется с ней. Чтобы получить метки времени, которые можно синхронизировать с внешней ссылкой на время, например в формате UTC, для использования в измерениях времени с высоким разрешением, используйте GetSystemTimePreciseAsFileTime.

Метки времени и измерения интервалов времени являются неотъемлемой частью измерений производительности компьютера и сети. Эти операции измерения производительности включают вычисление времени отклика, пропускной способности и задержки, а также выполнение кода профилирования. Каждая из этих операций включает в себя измерение действий, выполняемых в течение интервала времени, определенного событием начала и окончания, которое может быть независимо от любых внешних ссылок на время суток.

QPC обычно является лучшим методом для событий метки времени и измерения небольших интервалов времени, которые происходят в той же системе или виртуальной машине. Рассмотрите возможность использования GetSystemTimePreciseAsFileTime , если требуется использовать события метки времени на нескольких компьютерах при условии, что каждый компьютер участвует в схеме синхронизации времени, такой как протокол сетевого времени (NTP). QPC помогает избежать трудностей, которые могут возникнуть при других подходах к измерению времени, таких как чтение счетчика меток времени процессора (TSC) напрямую.

Поддержка QPC в версиях Windows

QPC появилась в Windows 2000 и Windows XP и развивалась, чтобы воспользоваться преимуществами усовершенствований аппаратной платформы и процессоров. Здесь мы описываем характеристики QPC в разных версиях Windows, чтобы помочь вам поддерживать программное обеспечение, работающее в этих версиях Windows.

Windows XP и Windows 2000

QPC доступен в Windows XP и Windows 2000 и хорошо работает в большинстве систем. Однако в BIOS некоторых аппаратных систем неправильно указаны характеристики ЦП оборудования (не инвариантный TSC), а в некоторых многоядерных или многопроцессорных системах использовались процессоры с TSC, которые не удалось синхронизировать между ядрами. Системы с несовершенным встроенным ПО, которые работают под управлением этих версий Windows, могут не обеспечивать одинаковое чтение QPC на разных ядрах, если они использовали TSC в качестве основы для QPC.

Windows Vista и Windows Server 2008

Все компьютеры, поставляемые с Windows Vista и Windows Server 2008, использовали счетчик платформы (таймер событий высокой точности (HPET)) или таймер управления питанием ACPI (таймер PM) в качестве основы для QPC. Такие таймеры платформы имеют более высокую задержку доступа, чем TSC, и совместно используются несколькими процессорами. Это ограничивает масштабируемость QPC , если он вызывается одновременно из нескольких процессоров.

Windows 7 и Windows Server 2008 R2

Большинство компьютеров Windows 7 и Windows Server 2008 R2 имеют процессоры с TSC с постоянной скоростью и используют эти счетчики в качестве основы для QPC. TSC — это аппаратные счетчики с высоким разрешением для каждого процессора, доступ к которым можно получить с очень низкой задержкой и накладными расходами (в зависимости от типа процессора в пределах 10-х или 100-х циклов компьютера). Windows 7 и Windows Server 2008 R2 используют TSC в качестве основы QPC в системах доменов с одним часовом режимом, где операционная система (или гипервизор) может тесно синхронизировать отдельные контроллеры безопасности во всех процессорах во время инициализации системы. В таких системах стоимость чтения счетчика производительности значительно ниже, чем в системах, использующих счетчик платформы. Кроме того, для параллельных вызовов нет дополнительных накладных расходов, а запросы в пользовательском режиме часто обходят системные вызовы, что еще больше сокращает затраты. В системах, где TSC не подходит для хранения времени, Windows автоматически выбирает счетчик платформы (таймер HPET или таймер ACPI PM) в качестве основы для QPC.

Windows 8, Windows 8.1, Windows Server 2012 и Windows Server 2012 R2

Windows 8, Windows 8.1, Windows Server 2012 и Windows Server 2012 R2 используют TSC в качестве основы для счетчика производительности. Алгоритм синхронизации TSC был значительно улучшен для лучшей адаптации крупных систем с большим количеством процессоров. Кроме того, добавлена поддержка нового API точного времени суток, который позволяет получать точные метки времени настенных часов из операционной системы. Дополнительные сведения см. в разделе GetSystemTimePreciseAsFileTime. На Windows RT и Windows 11 и Windows 10 устройствах, использующих процессоры Arm, счетчик производительности основан на собственном счетчике платформы или системном счетчике, предоставленном универсальным таймером Arm, если платформа так оснащена.

Руководство по получению меток времени

Windows и будет продолжать инвестировать в обеспечение надежного и эффективного счетчика производительности. Если вам нужны метки времени с разрешением 1 микросекунда или выше, а метки времени не нужно синхронизировать с внешней ссылкой на время, выберите QueryPerformanceCounter, KeQueryPerformanceCounter или KeQueryInterruptTimePrecise. Если вам нужны синхронизированные в формате UTC метки времени с разрешением 1 микросекунда или выше, выберите GetSystemTimePreciseAsFileTime или KeQuerySystemTimePrecise.

На относительно небольшом количестве платформ, которые не могут использовать регистр TSC в качестве основы QPC , например, по причинам, описанным в разделе Сведения о таймере оборудования, получение меток времени с высоким разрешением может быть значительно дороже, чем получение меток времени с более низким разрешением. Если достаточно разрешения от 10 до 16 миллисекундах, можно использовать GetTickCount64, QueryInterruptTime, QueryUnbiasedInterruptTime, KeQueryInterruptTime или KeQueryUnbiasedInterruptTime для получения меток времени, которые не синхронизированы с внешней ссылкой на время. Для меток времени, синхронизированных в формате UTC, используйте GetSystemTimeAsFileTime или KeQuerySystemTime. Если требуется более высокое разрешение, для получения меток времени можно использовать QueryInterruptTimePrecise, QueryUnbiasedInterruptTimePrecise или KeQueryInterruptTimePrecise .

Как правило, результаты счетчика производительности согласованы на всех процессорах в многоядерных и многопроцессорных системах, даже если они измеряются в разных потоках или процессах. Ниже приведены некоторые исключения из этого правила:

  • Операционные системы Windows Vista, работающие на определенных процессорах, могут нарушать эту согласованность по одной из следующих причин:

    • Аппаратные процессоры имеют не инвариантный TSC, и BIOS неправильно указывает на это условие.
    • Используемый алгоритм синхронизации TSC не подходит для систем с большим количеством процессоров.
  • При сравнении результатов счетчика производительности, полученных из разных потоков, учитывайте, что значения, отличающиеся ± 1 галочку, имеют неоднозначный порядок. Если метки времени взяты из одного потока, эта неопределенность ± 1 тика не применяется. В этом контексте термин tick обозначает период времени, равный 1 ÷ (частота счетчика производительности, полученного из QueryPerformanceFrequency).

При использовании счетчика производительности в крупных серверных системах с доменами с несколькими часами, которые не синхронизированы на оборудовании, Windows определяет, что TSC не может использоваться для целей времени, и выбирает счетчик платформы в качестве основы для QPC. Хотя этот сценарий по-прежнему дает надежные метки времени, задержка доступа и масштабируемость негативно сказывается. Поэтому, как уже говорилось в предыдущем руководстве по использованию, используйте API, которые обеспечивают разрешение в 1 микросекунда или выше, если такое разрешение необходимо. TSC используется в качестве основы для QPC в системах доменов с несколькими тактами, которые включают аппаратную синхронизацию всех доменов процессорных часов, так как это эффективно делает их функционирование в качестве единой системы доменов часов.

Частота счетчика производительности фиксирована при загрузке системы и согласована во всех процессорах, поэтому вам нужно запрашивать частоту из QueryPerformanceFrequency только при инициализации приложения, а затем кэшировать результат.

Виртуализация

Ожидается, что счетчик производительности будет надежно работать на всех гостевых виртуальных машинах, работающих на правильно реализованных гипервизорах. Однако низкоуровневые оболочки, которые соответствуют интерфейсу низкоуровневой оболочки версии 1.0 и повещают эталонное время, могут существенно снизить затраты. Дополнительные сведения об интерфейсах и просветлениях гипервизора см. в разделе Спецификации гипервизора.

Прямое использование TSC

Мы настоятельно рекомендуем использовать инструкцию процессора RDTSC или RDTSCP для прямого запроса TSC, так как вы не получите надежные результаты в некоторых версиях Windows, при динамической миграции виртуальных машин и в аппаратных системах без инвариантных или тесно синхронизированных TSC. Вместо этого мы рекомендуем использовать QPC для использования абстракции, согласованности и переносимости, которые он предлагает.

Примеры получения меток времени

В различных примерах кода в этих разделах показано, как получить метки времени.

Использование QPC в машинном коде

В этом примере показано, как использовать QPC в машинном коде C и C++.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

QueryPerformanceFrequency(&Frequency); 
QueryPerformanceCounter(&StartingTime);

// Activity to be timed

QueryPerformanceCounter(&EndingTime);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;


//
// We now have the elapsed number of ticks, along with the
// number of ticks-per-second. We use these values
// to convert to the number of elapsed microseconds.
// To guard against loss-of-precision, we convert
// to microseconds *before* dividing by ticks-per-second.
//

ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Получение меток времени с высоким разрешением из управляемого кода

В этом примере показано, как использовать управляемый код класса System.Diagnostics.Stopwatch .

using System.Diagnostics;

long StartingTime = Stopwatch.GetTimestamp();

// Activity to be timed

long EndingTime  = Stopwatch.GetTimestamp();
long ElapsedTime = EndingTime - StartingTime;

double ElapsedSeconds = ElapsedTime * (1.0 / Stopwatch.Frequency);

Класс System.Diagnostics.Stopwatch также предоставляет несколько удобных методов для измерения интервала времени.

Использование QPC из режима ядра

Ядро Windows предоставляет доступ к счетчику производительности в режиме ядра через KeQueryPerformanceCounter , из которого можно получить как счетчик производительности, так и частоту производительности. KeQueryPerformanceCounter доступен только в режиме ядра и предоставляется для записи драйверов устройств и других компонентов режима ядра.

В этом примере показано, как использовать KeQueryPerformanceCounter в режиме ядра C и C++.

LARGE_INTEGER StartingTime, EndingTime, ElapsedMicroseconds;
LARGE_INTEGER Frequency;

StartingTime = KeQueryPerformanceCounter(&Frequency);

// Activity to be timed

EndingTime = KeQueryPerformanceCounter(NULL);
ElapsedMicroseconds.QuadPart = EndingTime.QuadPart - StartingTime.QuadPart;
ElapsedMicroseconds.QuadPart *= 1000000;
ElapsedMicroseconds.QuadPart /= Frequency.QuadPart;

Общие вопросы и ответы о QPC и TSC

Ниже приведены ответы на часто задаваемые вопросы о QPC и TSC в целом.

Совпадает ли функция QueryPerformanceCounter() с функцией Win32 GetTickCount() или GetTickCount64()?

Нет. GetTickCount и GetTickCount64 не связаны с QPC. GetTickCount и GetTickCount64 возвращают количество миллисекунд с момента запуска системы.

Следует ли использовать QPC или вызывать инструкции RDTSC/RDTSCP напрямую?

Чтобы избежать ошибок и проблем с переносимостью, настоятельно рекомендуется использовать QPC вместо регистра TSC или инструкций процессора RDTSC или RDTSCP .

Каково отношение КПК к внешней временной эпохе? Можно ли синхронизировать ее с внешней эпохой, такой как UTC?

QPC основан на аппаратном счетчике, который не может быть синхронизирован с внешней ссылкой на время, например в формате UTC. Для точных меток времени суток, которые можно синхронизировать с внешней ссылкой в формате UTC, используйте GetSystemTimePreciseAsFileTime.

Влияет ли на QPC летнее время, високосные секунды, часовые пояса или изменения системного времени, внесенные администратором?

Нет. QPC полностью не зависит от системного времени и времени в формате UTC.

Влияет ли на точность QPC изменение частоты процессора, вызванное управлением питанием или технологией Turbo Boost?

Нет. Если процессор имеет инвариантный TSC, на QPC не влияют такие изменения. Если процессор не имеет инвариантного TSC, QPC будет отменить изменения на аппаратный таймер платформы, на который не влияют изменения частоты процессора или технология Turbo Boost.

Надежно ли работает QPC в многопроцессорных системах, многоядерных системах и системах с гиперпотоками?

Да.

Разделы справки определить и проверить, работает ли QPC на моем компьютере?

Такие проверки выполнять не нужно.

Какие процессоры имеют не инвариантные TSC? Как проверка, если в моей системе есть не инвариантный TSC?

Вам не нужно выполнять эту проверка себя. Операционные системы Windows выполняют несколько проверок при инициализации системы, чтобы определить, подходит ли TSC в качестве основы для QPC. Однако в справочных целях можно определить, имеет ли ваш процессор инвариантный TSC, используя одно из следующих средств:

  • служебная программа Coreinfo.exe из Windows Sysinternals
  • проверка значений, возвращаемых инструкцией CPUID, относящихся к характеристикам TSC
  • документация изготовителя процессора

Ниже показаны сведения TSC-INVARIANT, предоставляемые служебной программой Windows Sysinternals Coreinfo.exe (www.sysinternals.com). Звездочка означает "True".

> Coreinfo.exe 

Coreinfo v3.2 - Dump information on system CPU and memory topology
Copyright (C) 2008-2012 Mark Russinovich
Sysinternals - www.sysinternals.com

 <unrelated text removed>

RDTSCP          * Supports RDTSCP instruction
TSC             * Supports RDTSC instruction
TSC-DEADLINE    - Local APIC supports one-shot deadline timer
TSC-INVARIANT   * TSC runs at constant rate

Надежно ли работает QPC на Windows RT аппаратных платформах?

Да.

Как часто выполняется переворачение QPC?

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

Каковы вычислительные затраты на вызов QPC?

Стоимость вычислительных вызовов QPC определяется главным образом базовой аппаратной платформой. Если в качестве основы для QPC используется регистр TSC, стоимость вычислений определяется главным образом тем, сколько времени процессор занимает для обработки инструкции RDTSC . Это время колеблется от 10-х циклов ЦП до нескольких сотен циклов ЦП в зависимости от используемого процессора. Если TSC не удается использовать, система выберет другую аппаратную базу времени. Поскольку эти временные базы расположены на системной плате (например, на pci South Bridge или PCH), стоимость вычислений за вызов выше, чем на TSC, и часто находится в непосредственной близости от 0,8–1,0 микросекунд в зависимости от скорости процессора и других аппаратных факторов. Эта стоимость зависит от времени, необходимого для доступа к аппаратному устройству на системной плате.

Требуется ли для QPC переход ядра (системный вызов)?

Переход ядра не требуется, если система может использовать регистр TSC в качестве основы для QPC. Если система должна использовать другую базу времени, например таймер HPET или PM, требуется системный вызов.

Является ли счетчик производительности монотонным (не убывающей)?

Да. QPC не идет назад.

Можно ли использовать счетчик производительности для упорядочения событий во времени?

Да. Однако при сравнении результатов счетчика производительности, полученных из разных потоков, значения, отличающиеся ± 1 такта, имеют неоднозначное упорядочение, как если бы они имели одинаковую метку времени.

Насколько точен счетчик производительности?

Ответ зависит от различных факторов. Дополнительные сведения см. в разделе Низкоуровневые аппаратные характеристики часов.

Часто задаваемые вопросы о программировании с помощью QPC и TSC

Ниже приведены ответы на часто задаваемые вопросы о программировании с помощью QPC и TSC.

Мне нужно преобразовать выходные данные QPC в миллисекундах. Как избежать потери точности при преобразовании в double или float?

При выполнении вычислений с целочисленными счетчиками производительности следует учитывать несколько моментов:

  • Целочисленное деление потеряет остаток. В некоторых случаях это может привести к потере точности.
  • Преобразование между 64-разрядными целыми числами и числом с плавающей запятой (double) может привести к потере точности, так как мантисса с плавающей запятой не может представлять все возможные целочисленные значения.
  • Умножение 64-разрядных целых чисел может привести к переполнению целых чисел.

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

Как преобразовать QPC в 100 наносекундных тактов, чтобы добавить его в FILETIME?

Время файла — это 64-разрядное значение, представляющее количество 100-наносекундных интервалов, прошедших с 12:00 1 января 1601 г. в формате UTC. Время файлов используется вызовами API Win32, возвращающими время суток, например GetSystemTimeAsFileTime и GetSystemTimePreciseAsFileTime. Напротив, QueryPerformanceCounter возвращает значения, представляющие время в единицах 1/(частота счетчика производительности, полученной из QueryPerformanceFrequency). Для преобразования между ними необходимо вычислить соотношение интервала QPC и интервала 100 наносекунд. Будьте осторожны, чтобы не потерять точность, так как значения могут быть небольшими (0,0000001 / 0,0000000340).

Почему метка времени, возвращаемая из QPC, является целым числом со знаком?

Вычисления, включающие метки времени QPC , могут включать вычитание. С помощью подписанного значения можно обрабатывать вычисления, которые могут привести к отрицательным значениям.

Как получить метки времени с высоким разрешением из управляемого кода?

Вызовите метод Stopwatch.GetTimeStamp из класса System.Diagnostics.Stopwatch . Пример использования Stopwatch.GetTimeStamp см. в разделе Получение меток времени с высоким разрешением из управляемого кода.

При каких обстоятельствах QueryPerformanceFrequency возвращает значение FALSE, а QueryPerformanceCounter возвращает ноль?

Это не происходит ни в одной системе под управлением Windows XP или более поздней версии.

Нужно ли задать сходство потоков для одного ядра, чтобы использовать QPC?

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

Низкоуровневые характеристики аппаратных часов

В этих разделах показаны низкоуровневые характеристики аппаратных часов.

Абсолютные часы и разностные часы

Абсолютные часы обеспечивают точные значения времени суток. Обычно они основаны на формате UTC, и, следовательно, их точность частично зависит от того, насколько хорошо они синхронизированы с внешней ссылкой на время. Разностные часы измеряют интервалы времени и обычно не основаны на внешней эпохе времени. QPC — это разностные часы, которые не синхронизированы с внешней эпохой времени или ссылкой. При использовании QPC для измерений с интервалом времени вы обычно получаете лучшую точность, чем при использовании меток времени, производных от абсолютных часов. Это связано с тем, что процесс синхронизации времени абсолютных часов может привести к фазовой и частоте сдвигов, которые увеличивают неопределенность краткосрочных измерений интервала времени.

Разрешение, точность, точность и стабильность

В качестве основы QPC используется аппаратный счетчик. Аппаратные таймеры состоят из трех частей: генератора тактов, счетчика, который подсчитывает такты, и средства получения значения счетчика. Характеристики этих трех компонентов определяют разрешение, точность, точность и стабильность QPC.

Если аппаратный генератор предоставляет такты с постоянной скоростью, интервалы времени можно измерить, просто подсчитав эти такты. Скорость, с которой создаются такты, называется частотой и выражается в герцах (Гц). Обратная связь частоты называется периодом или тик-интервалом и выражается в соответствующей единице времени международной системы единиц (SI) (например, секунда, миллисекунда, микросекунда или наносекунда).

интервал времени

Разрешение таймера равно точке. Разрешение определяет возможность различать любые две метки времени и помещает нижнюю границу на наименьшие интервалы времени, которые можно измерить. Это иногда называется разрешением тактов.

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

цифровое измерение времени

Однако если измеряемый период невелик и приближается к разрешению таймера, необходимо учитывать эту квантирующую ошибку. Размер введенной ошибки равен размеру одного периода часов.

На следующих двух схемах показано влияние неопределенности ± 1 тик с помощью таймера с разрешением 1 единица времени.

неопределенность тактов

QueryPerformanceFrequency возвращает частоту QPC, а период и разрешение равны обратному значению этого значения. Частота счетчика производительности, возвращаемая QueryPerformanceFrequency , определяется во время инициализации системы и не изменяется во время работы системы.

Примечание

Часто QueryPerformanceFrequency не возвращает фактическую частоту аппаратного генератора тактов. Например, в некоторых более старых версиях Windows QueryPerformanceFrequency возвращает частоту TSC, деля ее на 1024; и при запуске в гипервизоре , который реализует интерфейс гипервизора версии 1.0 (или всегда в некоторых более новых версиях Windows), частота счетчика производительности фиксируется до 10 МГц. В результате не предполагайте, что QueryPerformanceFrequency вернет значение, производное от аппаратной частоты.

 

QueryPerformanceCounter считывает счетчик производительности и возвращает общее количество тактов, произошедших с момента запуска операционной системы Windows, включая время, когда компьютер находился в спящем режиме, например в режиме ожидания, гибернации или подключенного режима ожидания.

В этих примерах показано, как вычислить интервал и разрешение тактов, а также преобразовать число тактов в значение времени.

Пример 1

QueryPerformanceFrequency возвращает значение 3 125 000 на определенном компьютере. Каков интервал тактов и разрешение измерений QPC на этом компьютере? Интервал деления, или период, является обратным значением 3 125 000, то есть 0,000000320 (320 наносекунд). Таким образом, каждый такт представляет собой прохождение 320 наносекунд. Интервалы времени меньше 320 наносекунд не могут быть измерены на этом компьютере.

Интервал тактов = 1/(Частота производительности)

Интервал тактов = 1/3 125 000 = 320 нс

Пример 2

На том же компьютере, что и в предыдущем примере, разница значений, возвращаемых двумя последовательными вызовами QPC , составляет 5. Сколько времени прошло между двумя звонками? 5 тактов, умноженные на 320 наносекунд, дают 1,6 микросекунд.

ElapsedTime = Тактов * Интервал тактов

ElapsedTime = 5 * 320 ns = 1,6 мкс

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

Precision = MAX [ Resolution, AccessTime]

Например, рассмотрим гипотетический аппаратный таймер с разрешением 100 наносекунд и временем доступа 800 наносекунд. Это может быть так, если в качестве основы QPC использовался таймер платформы вместо регистра TSC. Таким образом, точность будет составлять 800 наносекунд, а не 100 наносекунд, как показано в этом вычислении.

Точность = MAX [800 нс,100 нс] = 800 нс

Эти две цифры изображают этот эффект.

Время доступа qpc

Если время доступа превышает разрешение, не пытайтесь повысить точность путем угадки. Иными словами, ошибочно предположить, что метка времени взята именно в середине, в начале или в конце вызова.

В отличие от этого, рассмотрим следующий пример, в котором время доступа QPC составляет только 20 наносекунд, а разрешение аппаратных часов — 100 наносекунд. Это может быть так, если регистр TSC использовался в качестве основы для QPC. Здесь точность ограничена разрешением часов.

точность qpc

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

Эта таблица содержит сведения о приблизительном разрешении, времени доступа и точности различных часов. Обратите внимание, что некоторые значения зависят от разных процессоров, аппаратных платформ и скоростей процессора.

Источник часов Номинальная тактовая частота Разрешение часов Время доступа (обычное) Точность
PC RTC 64 Гц 15,625 миллисекунда Н/Д Н/Д
Счетчик производительности запросов с помощью TSC с тактовой частотой процессора 3 ГГц 3 МГц 333 наносекунд 30 наносекунд 333 наносекунд
Машинная инструкция RDTSC в системе с циклом 3 ГГц 3 ГГц 333 пикосекунда 30 наносекунд 30 наносекунд

 

Так как QPC использует аппаратный счетчик, при понимании некоторых основных характеристик аппаратных счетчиков вы получите представление о возможностях и ограничениях QPC.

Наиболее часто используемым аппаратным генератором тактов является кристаллический осциллятор. Кристалл представляет собой небольшой кусок кварца или другого керамического материала, который проявляет пьезоэлектрические характеристики, обеспечивающие недорогой эталон частоты с отличной стабильностью и точностью. Эта частота используется для создания тактов, подсчитываемых часами.

Точность таймера относится к степени соответствия значению true или стандарту. Это зависит в первую очередь от способности кристаллического осциллятора предоставлять такты с указанной частотой. Если частота колебаний слишком высока, часы будут "работать быстро", а измеренные интервалы кажутся длиннее, чем они есть на самом деле; и если частота слишком низкая, часы будут работать медленно, а измеренные интервалы будут короче, чем они есть на самом деле.

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

Частота колебаний кристаллов устанавливается во время производственного процесса и указывается производителем с точки зрения указанной частоты плюс или минус погрешность производства, выраженная в "частях на миллион" (ppm), называемом максимальной частотой смещения. Кристалл с заданной частотой 1 000 000 Гц и максимальным смещением частоты ± 10 ppm будет находиться в пределах спецификации, если бы его фактическая частота находилась в диапазоне от 999 990 Гц до 1 000 010 Гц.

Заменив количество частей фразы на миллион микросекундами в секунду, мы можем применить эту ошибку смещения частоты к измерениям интервала времени. Осциллятор со смещением + 10 ppm будет иметь ошибку 10 микросекунд в секунду. Соответственно, при измерении интервала в 1 секунду он будет выполняться быстро и измерять интервал в 1 секунду как 0,999990 секунды.

Удобная ссылка заключается в том, что ошибка частоты 100 ppm вызывает ошибку в 8,64 секунды через 24 часа. В этой таблице представлена неопределенность измерения из-за накопленных ошибок в течение более длительных интервалов времени.

Длительность интервала времени Неопределенность измерения из-за накопленных ошибок с допуском частоты +/- 10 PPM
1 микросекунда ± 10 пикосеконд (10-12)
1 миллисекунда ± 10 наносекунд (10–9)
1 с ± 10 микросекунд
1 час ± 60 микросекунд
1 день ± 0,86 секунды
1 неделя ± 6,08 секунды

 

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

Кристаллические осцилляторы, используемые на персональных компьютерах и серверах, обычно производятся с допуском частоты ± 30–50 частей на миллион, и редко кристаллы могут быть выключены на целых 500 ppm. Хотя доступны кристаллы с гораздо более жесткими допусками смещения частоты, они стоят дороже и, следовательно, не используются на большинстве компьютеров.

Чтобы уменьшить негативные последствия этой ошибки смещения частоты, последние версии Windows, особенно Windows 8, используют несколько аппаратных таймеров для обнаружения смещения частоты и его компенсации по возможности. Этот процесс калибровки выполняется при запуске Windows.

Как показано в следующих примерах, ошибка смещения частоты аппаратных часов влияет на достижимую точность, и разрешение часов может быть менее важным.

Ошибка смещения частоты влияет на достижимую точность

Пример 1

Предположим, вы выполняете измерения интервала времени с помощью осциллятора 1 МГц, который имеет разрешение 1 микросекунд и максимальную ошибку смещения частоты ±50 ppm. Теперь предположим, что смещение равно +50 ppm. Это означает, что фактическая частота будет составлять 1 000 050 Гц. Если мы измеряем интервал времени в 24 часа, наше измерение было бы слишком коротким 4,3 секунды (23:59:55,700000 по сравнению с 24:00:00,000000 фактическим).

Секунд в день = 86400

Ошибка смещения частоты = 50 ppm = 0,00005

86 400 секунд * 0,00005 = 4,3 секунды

Пример 2

Предположим, что часы TSC процессора управляются кристаллическими осцилляторами и имеют заданную частоту 3 ГГц. Это означает, что разрешение будет составлять 1/3 000 000 000 или около 333 пикосекунда. Предположим, что кристалл, используемый для управления процессором, имеет допуск частоты ±50 ppm и фактически составляет +50 ppm. Несмотря на впечатляющее разрешение, измерение интервала времени в 24 часа по-прежнему будет слишком коротким на 4,3 секунды. (23:59:55.7000000000 по сравнению с 24:00:00.0000000000 фактическим значением).

Секунд в день = 86400

Ошибка смещения частоты = 50 ppm = 0,00005

86 400 секунд * 0,00005 = 4,3 секунды

Это показывает, что часы TSC с высоким разрешением не обязательно обеспечивают более точные измерения, чем часы с низким разрешением.

Пример 3

Рассмотрите возможность использования двух разных компьютеров для измерения одного и того же 24-часового интервала времени. Оба компьютера имеют осциллятор с максимальным смещением частоты ± 50 ppm. Насколько далеко друг от друга может быть измерение одного и того же интервала времени в этих двух системах? Как и в предыдущих примерах, ± 50 ppm дает максимальную ошибку ± 4,3 секунды через 24 часа. Если одна система работает 4,3 секунды быстрее, а другая — 4,3 секунды медленно, максимальная ошибка через 24 часа может составлять 8,6 секунды.

Секунд в день = 86400

Ошибка смещения частоты = ±50 ppm = ±0,00005

±(86 400 секунд * 0,00005) = ±4,3 секунды

Максимальное смещение между двумя системами = 8,6 секунды

Таким образом, ошибка смещения частоты становится все более важной при измерении длительных интервалов времени и при сравнении измерений между различными системами.

Стабильность таймера определяет, изменяется ли частота тактов с течением времени, например в результате изменения температуры. Кристаллы кварца, используемые в качестве генераторов тактов на компьютерах, будут демонстрировать небольшие изменения частоты в качестве функции температуры. Ошибка, вызванная тепловым смещением, обычно невелика по сравнению с ошибкой смещения частоты для общих диапазонов температур. Однако разработчикам программного обеспечения для переносного оборудования или оборудования, подверженного большим колебаниям температуры, может потребоваться рассмотреть этот эффект.

Сведения о таймере оборудования

Регистр TSC (x86 и x64)

Все современные процессоры Intel и AMD содержат регистр TSC, который представляет собой 64-разрядный регистр, который увеличивается с высокой скоростью, обычно равной тактовой частоте процессора. Значение этого счетчика можно считывать с помощью инструкций компьютера RDTSC или RDTSCP , обеспечивая очень низкое время доступа и вычислительные затраты в порядке десятков или сотен циклов компьютера в зависимости от процессора.

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

  • Не все процессоры имеют пригодные для использования регистры TSC, поэтому использование регистра TSC в программном обеспечении напрямую создает проблему переносимости. (В этом случае Windows выберет альтернативный источник времени для QPC , что позволит избежать проблем с переносимостью.)
  • Некоторые процессоры могут изменять частоту часов TSC или останавливать продвижение регистра TSC, что делает TSC непригодным для временных целей на этих процессорах. Говорят, что эти процессоры имеют не инвариантные регистры TSC. (Windows автоматически обнаружит это и выберет альтернативный источник времени для QPC).
  • Даже если узел виртуализации имеет доступную для использования TSC, динамическая миграция работающих виртуальных машин, когда целевой узел виртуализации не имеет или использует масштабирование TSC с аппаратным обеспечением, может привести к изменению частоты TSC, видимой для гостей. (Ожидается, что если этот тип динамической миграции возможен для гостя, гипервизор очищает инвариантный бит функции TSC в CPUID.)
  • В многопроцессорных или многоядерных системах некоторые процессоры и системы не могут синхронизировать часы на каждом ядре с одинаковым значением. (Windows автоматически обнаружит это и выберет альтернативный источник времени для QPC).
  • В некоторых крупных многопроцессорных системах вы не сможете синхронизировать часы процессора с одинаковым значением, даже если процессор имеет инвариантный TSC. (Windows автоматически обнаружит это и выберет альтернативный источник времени для QPC).
  • Некоторые процессоры будут выполнять инструкции не по порядку. Это может привести к неправильному подсчету циклов, если RDTSC используется для последовательностей инструкций по времени, так как инструкция RDTSC может выполняться в другое время, чем указано в вашей программе. Инструкция RDTSCP была введена на некоторых процессорах в ответ на эту проблему.

Как и другие таймеры, TSC основан на кристаллическом осцилляторе, точная частота которого не известна заранее и имеет ошибку смещения частоты. Таким образом, прежде чем его можно будет использовать, его необходимо откалиброть с помощью другой ссылки на время.

Во время инициализации системы Windows проверяет, подходит ли TSC для временных целей, и выполняет необходимую калибровку частоты и синхронизацию ядра.

Часы PM (x86 и x64)

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

Таймер HPET (x86 и x64)

Таймер событий высокой точности (HPET) был разработан совместно корпорацией Intel и Корпорацией Майкрософт в соответствии с требованиями к времени для мультимедийных и других приложений, чувствительных к времени. В отличие от TSC, который является ресурсом для каждого процессора, HPET является общим ресурсом для всей платформы, хотя система может иметь несколько HPET. Поддержка HPET реализована в Windows с Windows Vista, а для Сертификации Windows 7 и Windows 8 hardware Logo требуется поддержка HPET на аппаратной платформе.

Универсальный системный счетчик таймера (ARM)

На платформах на основе arm нет часов TSC, HPET или PM, как на платформах intel или AMD. Вместо этого процессоры Arm предоставляют универсальный таймер (иногда называемый таймером универсального интервала или GIT), который содержит реестр системного счетчика (например, CNTVCT_EL0). Универсальный системный счетчик таймера — это источник времени на уровне платформы с фиксированной частотой. Он начинается с нуля при запуске и увеличивается с высокой скоростью. В Armv8.6 или более поздней версии это значение определяется как ровно 1 ГГц, но должно определяться путем считывания регистра тактовой частоты, заданного при ранней загрузке встроенного ПО. Дополнительные сведения см. в разделе "Универсальный таймер в состоянии AArch64" статьи "Справочное руководство по архитектуре Arm для архитектуры A-profile" (DDI 0487).

Счетчик циклов (arm)

Платформы на основе arm предоставляют регистр счетчика циклов системных мониторов (например, PMCCNTR_EL0). Этот счетчик подсчитывает тактовые циклы процессора. Он не является инвариантным, и его единицы не могут быть связаны с режимом реального времени. Не рекомендуется использовать этот регистр для получения меток времени.