Как реализован 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, хотя последнее по-прежнему хорошо читается.