Вызов NtQueryTimerResolution()
вернет значение для ActualResolution .В вашем случае реальное разрешение почти наверняка составляет 0,9765625 мс.Это именно то, что вы показываете в первом сюжете.Второй интервал около 1,95 мс точнее Sleep(1)
= 1,9531 мс = 2 х 0,9765625 мс
Я полагаю, что период прерывания длится примерно до 1 мс (0,9765625).
А теперь начинается проблема: таймер сигнализирует о истечении требуемой задержки.
Скажем, ActualResolution установлен на 0,9765625, сердцебиение прерывания системы будет выполняться с периодами 0,9765625 мс или 1024 Гц, и вызов Sleep
будет выполнен с желаемой задержкой 1Миз.Необходимо рассмотреть два сценария:
- Вызов был сделан <1 мс (ΔT) перед следующим прерыванием.Следующее прерывание не подтвердит, что желаемый период времени истек.Только следующее прерывание вызовет возврат вызова.Результирующая задержка ожидания будет ΔT + 0,9765625 мс. </li>
- Вызов был сделан> = 1 мс (ΔT) перед следующим прерыванием.Следующее прерывание заставит звонок вернуться.Результирующая задержка сна будет ΔT.
Таким образом, результат во многом зависит от того, когда был сделан вызов, и поэтому вы можете наблюдать события 0,98 мс, а также события 1,95 мс.
Редактировать: Использование CreateTimerQueueTimer
приведет к увеличению наблюдаемой задержки до 1,95, поскольку тик таймера (период прерывания) равен 0,9765625 мс.При первом возникновении прерывания запрошенная длительность в 1 мс не истекла, поэтому TimerProc
будет срабатывать только после второго прерывания (2 x 0,9765625 мс = 1,9953125 мс> 1 мс).Следовательно, график queueTimer показывает пик в 1,953125 мс.
Примечание. Это поведение сильно зависит от базового оборудования.
Дополнительные сведения можно найти в проекте отметки времени Windows * 1033.*