2010-09-30 7 views
2

Я знаю, что могу использовать IRQ0, который является системным таймером, но это основано на тактовых сигналах 14.31818 МГц, верно? Есть ли что-то, предлагающее большую точность?Каков наиболее точный способ измерения прошедшего времени на современном ПК?

Спасибо.

Редактировать: Кто-нибудь знает, что использует функция Windows QueryPerformanceCounter?

+0

Это на самом деле 14.31818 МГц/12 = 1.193181 МГц. Обратите внимание, что это мегагерцы, т. Е. Миллионы циклов в секунду, какая прецессия вам нужна? Если вам не нужна TSC-подобная прецизионность, возможно, HPET будет достаточно? – ninjalj

+0

Хм, я получаю противоречивую информацию. Некоторые источники говорят 14.31818MHz, другие просто говорят «системные часы», и теперь вы говорите, что это 1,193181 МГц. Смущенный. – FSD

+0

http://dx.doi.org/10.1016/0745-7138(89)90029-8 говорит 1.19318 МГц. –

ответ

1

Процессоры Intel обычно имеют информацию о высокой точности таймера, доступную по инструкции rdtsc.

Он имеет гораздо более высокую точность, чем 14 МГц ¹. Предостережение заключается в том, что он может иметь проблемы с многоядерными процессорами и степпингом.

Редактировать:This question имеет гораздо более подробную информацию по этому вопросу.


1. Фактическая частота зависит от процессора - но часто частота процессора. По-видимому, на процессорах Nehalem TSC работает на частоте шины фронтальной шины (133 МГц).

+0

IIRC, RDTSC существует с Pentium и используется как счетчик циклов. Является ли это разумным или нет, зависит от процессора; есть некоторые флагов процессора для того, изменяется ли он с частотой процессора (в Linux, constant_tsc в/proc/cpuinfo), но даже с константой_tsc все равно могут быть затронуты состояниями сна. –

+0

@tc: также, независимо от того, синхронизирована ли она между различными процессорами/ядрами, зависит от процессора. – ninjalj

2

«Точность» и «точность» означают разные вещи. «Окружность Земли 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).