Таймеры с разрешением лучше 100 нс в Windows - PullRequest
2 голосов
/ 01 августа 2020

Я работаю над профилировщиком языка программирования и ищу таймер для Windows с разрешением лучше 100 нс.

  • QueryPerformanceCounter должно быть ответом, но возвращаемая частота QueryPerformanceFrequency составляет 10 МГц на Windows 10 и даже меньше на Windows 7

  • GetSystemTimePreciseAsFileTime имеет тик / шаг 100 нс

  • RDTSC имеет разрешение лучше 1 нс, но оно зависит от частоты

Мое целевое разрешение составляет не менее 10 нс.

Какое сейчас лучшее решение?

Как QueryPerformanceCounter реализовано? можно ли его легко разобрать и увеличить разрешение?

Возможно ли как-то использовать RDTSC напрямую и отслеживать / прерывать при каждом изменении частоты?

1 Ответ

3 голосов
/ 01 августа 2020

Как реализован QueryPerformanceCounter?

QP C таймер имеет разные реализации в HAL в зависимости от оборудования; в нем используются таймеры TS C, HPET, RT C, API C, ACPI или 8254, в зависимости от доступности.

QP C разрешение таймера жестко запрограммировано на 100 нс. Но это не имеет значения, потому что сам вызов QP C занимает> 100 нс. 100 нс - это очень, очень короткий промежуток времени в мире Windows.

RDTSC имеет разрешение лучше 1 нс, но оно зависит от частоты

Нет правда, частота TS C на самом деле довольно стабильна со времен Nehalem. См. Intel 64 Architecture SDM vol. 3A, «17.16 Invariant TS C»:

Семейства процессоров увеличивают счетчик отметок времени по-разному:

  • Для процессоров Pentium M (семейство [06H ], модели [09H, 0DH]); для процессоров Pentium 4, процессоров Intel Xeon (семейство [0FH], модели [00H, 01H или 02H]); и для процессоров семейства P6: счетчик отметок времени увеличивается с каждым внутренним тактовым циклом процессора. Такт внутреннего процессора определяется текущим соотношением частоты ядра к частоте шины. Переход на технологию Intel SpeedStep также может повлиять на тактовую частоту процессора.

  • Для процессоров Intel Xeon (семейство [0FH], модели [03H и выше]); для процессоров Intel Core Solo и Intel Core Duo (семейство [06H], модель [0EH]); для процессоров Intel Xeon серии 5100 и Intel Core 2 Duo (семейство [06H], модель [0FH]); для процессоров Intel Core 2 и Intel Xeon (семейство [06H], DisplayModel [17H]); для процессоров Intel Atom (семейство [06H], DisplayModel [1CH]): счетчик отметок времени увеличивается с постоянной скоростью. Эта частота может быть установлена ​​максимальным соотношением частоты ядра к частоте шины процессора или может быть установлена ​​максимальной разрешенной частотой, с которой загружается процессор. Максимальная разрешенная частота может отличаться от базовой частоты процессора, подробнее см. Раздел 18.18.2. На некоторых процессорах частота TS C может не совпадать с частотой в строке бренда.

Счетчик отметок времени в новых процессорах может поддерживать улучшение, называемое инвариант TS C. Поддержка процессором инварианта TS C обозначена CPUID.80000007H:EDX[8]. Инвариант TS C будет работать с постоянной скоростью во всех ACPI P-, C -. и Т-состояния. Это архитектурное поведение, которое движется вперед. На процессорах с постоянной поддержкой TS C ОС может использовать TS C для служб таймера настенных часов (вместо таймеров ACPI или HPET). Чтение TS C намного эффективнее и не требует накладных расходов, связанных с переходом по кольцу или доступом к ресурсу платформы.

Таким образом, для быстрых измерений вы должны иметь возможность использовать __rdtsc или __rdtscp. Вы можете откалибровать частоту TS C во время запуска и убедиться, что она не зависит от состояния процессора. Тем не менее, поток все еще может быть вытеснен, поэтому рекомендуется повторить измерение несколько раз или использовать QueryThreadCycleTime (хотя, конечно, это связано с собственными накладными расходами). На практике я считаю, что RDTSC не так плохо, как в Вычислить системное время, используя rdts c, хотя последнее по-прежнему хорошо читается.

...