«Точность» и «точность» означают разные вещи. «Окружность Земли 40000.000000000 км» является точной, но неточной. Это немного сложнее с часами:
- Разрешение: время между тиками или периодом тиков. (Возможно, вы могли бы назвать это «точностью», но я думаю, что «разрешение» имеет более очевидное значение.)
- Косые: относительная разница между номинальной и фактической тактовой частотой (ish)
- Дрейф: скорость изменения косы (из-за старения, температуры, ...).
- Дрожание: случайное изменение времени тика.
- Задержка: сколько времени требуется, чтобы получить метку времени.
Несмотря на то, что «системный таймер» (PIT согласно Википедии) работает на частоте 1 МГц, вы обычно получаете IRQ0 где-то между 100 и 1000 Гц. Apparently вы также можете прочитать из порта 0x40 дважды, чтобы получить текущее значение счетчика, но я не уверен, что это за латентность (а затем вы получаете количество отсчетов до следующего прерывания, поэтому вам нужно сделать некоторую математику) , Он также не работает на более современных «безклеточных» ядрах.
Есть несколько других высокочастотных таймеров:
- Local APIC, который основан на частоте шины и делителя мощности из-2. Я не могу найти какую-либо документацию о том, как ее прочитать (предположительно это порт ввода-вывода?).
- Таймер управления питанием ACPI (acpi_pm в Linux, я думаю, и флаг загрузки Windows/UsePMTimer), который составляет около 3,58 МГц согласно this. IIRC, читая его немного дороже.
- HPET, который составляет не менее 10 МГц по той же ссылке (но может быть выше). Он также должен иметь более низкую задержку, чем таймер ACPI PM.
- TSC (с оговорками). Почти наверняка самая низкая задержка и, вероятно, самая высокая частота.(Но, видимо, он может подняться более чем на 1 каждый «тик», поэтому рассчитывает за-вторых, не обязательно совпадает с разрешением.)
Darwin (i.e. OS X) по-видимому, предположить, что частота TSC не изменять и настраивать базовое значение, добавленное к нему при пробуждении из состояния ожидания, когда TSC не работает (по-видимому, C4 и выше). Для каждого процессора существует другое базовое значение, поскольку TSC не нужно синхронизировать между процессорами. Вы должны приложить разумные усилия, чтобы получить разумную метку времени.
IIRC, Linux просто выбирает один источник синхронизации (TSC, если он нормальный, а затем HPET, а затем ACPI PM, я думаю).
IIRC, QueryPerformanceCounter() использует то, что Windows считает лучшим. Это также зависит от версии Windows (XP якобы не поддерживает HPET для прерываний, поэтому, по-видимому, это также не относится к временным меткам). Вы можете вызвать QueryPerformanceFrequency(), чтобы сделать предположение (я получаю 1995030000, что, вероятно, означает, что это TSC).
Это на самом деле 14.31818 МГц/12 = 1.193181 МГц. Обратите внимание, что это мегагерцы, т. Е. Миллионы циклов в секунду, какая прецессия вам нужна? Если вам не нужна TSC-подобная прецизионность, возможно, HPET будет достаточно? – ninjalj
Хм, я получаю противоречивую информацию. Некоторые источники говорят 14.31818MHz, другие просто говорят «системные часы», и теперь вы говорите, что это 1,193181 МГц. Смущенный. – FSD
http://dx.doi.org/10.1016/0745-7138(89)90029-8 говорит 1.19318 МГц. –