Разрешение микросекунды устанавливает метку времени в Windows

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

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

Существует Реализация Непрерывно Обновление, Поставщик Времени С высоким разрешением для Windows, но это, кажется, не твердо. Когда вопрос микросекунд выглядит большим, но это больше не доступно для скачивания.

Другой ресурс Получает Точные Метки времени под Windows XP, но требуется много шагов, запуская программу помощника плюс некоторый материал init также, я не уверен, работает ли он над несколькими центральными процессорами.

Я также посмотрел на Счетчик Метки времени статьи Wikipedia, который интересен, но не настолько полезен.

Если ответ, просто делают это с BSD или Linux, это намного легче, и это прекрасно, но я хотел бы подтвердить это и получить некоторое объяснение относительно того, почему это так твердо в Windows и так легко в Linux и BSD. Это - те же прекрасные аппаратные средства...

16
задан Arno 7 August 2013 в 07:26
поделиться

6 ответов

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

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

QueryPerformanceCounter не всегда работает с тактовой частотой процессора. Фактически, он может попытаться избежать RDTSC , особенно в многопроцессорных (/ многоядерных) системах: он будет использовать HPET в Windows Vista и более поздних версиях, если он доступен, или таймер ACPI / PM . В моей системе (Windows 7 x64, двухъядерный AMD) таймер работает на частоте 14,31818 МГц.

То же самое верно и для более ранних систем:

По умолчанию Windows Server 2003 с пакетом обновления 2 (SP2) использует таймер PM для всех многопроцессорных APIC или ACPI HAL, если только процесс проверки, чтобы определить, поддерживает ли BIOS APIC или ACPI HAL не работает ».

Проблема в том, что проверка не удалась. Это просто означает, что ваш компьютер / BIOS каким-то образом не работает. Затем вы можете либо исправить свой BIOS (рекомендуется), либо, по крайней мере, переключиться на использование Таймер ACPI (/ usepmtimer) на данный момент.

Из C # легко - без P / Invoke - проверить поддержку таймера высокого разрешения с помощью Секундомер .IsHighResolution , а затем загляните в Stopwatch.Frequency . Это вызовет необходимый QueryPerformanceCounter изнутри.

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

Это означает, что вы действительно можете положиться на QueryPerformanceCounter.

... и вопреки распространенному мнению, QueryPerformanceFrequency () «не может изменяться во время работы системы» .

Редактировать: Как указано в документации по QueryPerformanceCounter () , «не имеет значения, какой процессор вызывается» - и на самом деле вся работа с привязкой к потоку необходима только в том случае, если обнаружение APIC / ACPI происходит сбой, и система прибегает к использованию TSC . Это курорт, которого не должно быть. Если это происходит в старых системах, скорее всего, производитель установил обновление BIOS или исправление драйверов. Если его нет, значит, загрузочный переключатель / usepmtimer все еще присутствует. Если и это не удастся, поскольку в системе нет надлежащего таймера, кроме Pentium TSC, вы можете подумать о том, чтобы возиться с привязкой потоков - даже в этом случае образец, предоставленный другими в области «Содержимое сообщества» на странице, является вводит в заблуждение, так как имеет немаловажные накладные расходы из-за настройки сходства потоков при каждом вызове запуска / остановки, что приводит к значительной задержке и, вероятно, снижает преимущества использования таймера с высоким разрешением в первую очередь.

Время игры и многоядерные процессоры - это рекомендация по их правильному использованию. Пожалуйста, примите во внимание, что сейчас пять лет, и в то время меньше систем были полностью совместимы / поддерживались ACPI - вот почему, несмотря на это, в статье так подробно рассказывается о TSC и о том, как обойти эту проблему. его ограничения, связанные с сохранением аффинной нити.

Я считаю, что в настоящее время довольно сложно найти обычный ПК с нулевой поддержкой ACPI и без использования таймера PM. Наиболее частым случаем, вероятно, является настройки BIOS, когда поддержка ACPI установлена ​​неправильно (иногда, к сожалению, по заводским настройкам).

Анекдоты рассказывают , что восемь лет назад в редких случаях ситуация была иной. (Читает весело, разработчики работают над «недостатками» дизайна и критикуют разработчиков микросхем. Честно говоря, может быть так же и наоборот.: -)

19
ответ дан 30 November 2019 в 15:35
поделиться

QueryPerformanceCounter / QueryPerformanceFrequency, разрешение скорости процессора

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

Дополнительная информация содержится в Получение точных отметок времени в Windows XP .

Если вам все же придется прибегнуть к этому методу:

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

11
ответ дан 30 November 2019 в 15:35
поделиться

Я не думаю, что вы найдете решение лучше, чем QueryPerformanceCounter. Стандартный метод заключается в настройке кода для перехвата и отбрасывания обратных скачков времени и массивных выбросов, которые могут возникнуть в результате переключения потоков ЦП. Если вы измеряете очень маленькие интервалы (если нет, то вам не нужна такая точность), то это не обычное явление. Просто сделайте это терпимой ошибкой, а не критической ошибкой.

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

5
ответ дан 30 November 2019 в 15:35
поделиться
  1. Windows не является ОС реального времени.

  2. Процессы в многозадачной ОС должны уступать свое время другому потоку/процессу. Это дает некоторые накладные расходы на синхронизацию.

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

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

  5. Некоторые ОС, такие как Linux или BSD, лучше, но они все равно не могут поддерживать точное временное разрешение до субмикросекунд (например, точность nanosleep() в Linux составляет около 1 мс, не менее 1 мс), если только вы не подстроите ядро под какой-то специфический планировщик, который даст вашему приложению преимущества.

Поэтому я думаю, что лучше адаптировать ваше приложение для решения этих проблем, например, часто перекалибруя вашу рутину синхронизации, что и обеспечивают ваши ссылки. AFAIK, самым высоким разрешением таймера для Windows по-прежнему является GetPerformanceCounter/Frequency(), независимо от его точности. Вы можете добиться большей точности, запустив процедуру объединения таймеров в отдельном потоке, установив его привязку к одному ядру процессора, и установив приоритет потока как можно выше.

6
ответ дан 30 November 2019 в 15:35
поделиться

Я использовал класс DateTimePrecise из Проект кода .

Единственная проблема, с которой я столкнулся, это то, что это дало бы сумасшедшие результаты, если бы я не называл его хотя бы каждые 10 секунд - я думаю, что внутри было какое-то целочисленное переполнение - так что у меня есть таймер, который выполняет DateTimePrecise.Now каждые несколько секунд.

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

Удачи ...

1
ответ дан 30 November 2019 в 15:35
поделиться

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

См. QueryPerformanceCounter

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

6
ответ дан 30 November 2019 в 15:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: