Тестирование
Разумеется, в мире нет ничего абсолютного. А тем более когда дело касается столь нереалтаймовой системы как Уиндоус. Впрочем, в случае real-time OS вопрос о таймерах вообще бы не стоял. А в наших условиях вполне может найтись в системе какой-нибудь хулиганский поток с высоким приоритетом (выше или равным нашему), который наглым образом будет отбирать управление на длительное время (больше длительности внутреннего цикла таймерного менеджера - 10 мс). И тогда наш таймер будет пропускать "тики" на коротких заданных интервалах и увеличивать погрешность на длинных. Это происходит в том случае, если кто-то работает не по правилам, либо производительности процессора не хватает для работы системы.
В целях проверки и демонстрации функционирования таймерного менеджера, а также сравнительного анализа со стандартным таймером была разработана демо-программа ().
Сравнивались: компонент TTimer, два интервальных таймера с разными способами уведомления (сообщение окну и асинхронный вызов), один синхронизированный таймер. Подсчитывалось количество срабатываний. Каждый факт срабатывания таймера записывался в журнал (TMemo), что также играло роль полезной нагрузки в работе приложения (попросту отъедание процессорного времени). Дополнительная нагрузка по инициативе пользователя эмулировалась задержкой (sleep) в обработчике событи OnClick кнопки. Одновременно контролировалась загрузка процессора по показаниям Windows NT Task Manager.
Проведенные исследования показали (см. таблицу), что интервальный таймер ведет себя почти идеально от 100 мс и достаточно хорошо на более мелких интервалах, тогда как стандартный таймер на коротких интервалах, а особенно под нагрузкой совсем сдает позиции. На интервале 10 мс интенсивная обработка извещений от таймеров (обновление контролов, особенно TMemo) приводит к 100% загрузке процессора. Синхронизированный таймер (FixedTimer), заряженный на минимальный интервал 1 с, всегда давал точное число тиков, причем срабатывал в начале секунды с небольшим разбросом.
От способа уведомления количество полученных тиков не зависело. При большой нагрузке и высокой частоте приложение могло получать уведомления PostMessage неравномерно (пачками накопленных в очереди сообщений), но общее число выдерживалось, насколько это возможно.
Результаты приведены для следующей конфигурации: Cyrix 6x86PR233/64M/WinNT4. Измерения проводились также на платформе Win98SE, где IntervalTimer показал примерно те же результаты, а TTimer еще более худшие.
Нормальные условия | |||||
100 | 10000 | 100 | 99 | 100 | 3-12 |
100 | 100000 | 1000 | 998 | 1000 | 3-12 |
10 | 10000 | 1000 | 659 | 999 | 100 |
10 | 100000 | 10000 | 6361 | 9991 | 100 |
15 | 10000 | 667 | 482 | 667 | 44-60 |
Нагрузка приложения (задержка на 2000 мс) | |||||
100 | 10000 | 100 | 79 | 100 | 2-17 |
15 | 10000 | 667 | 333 | 667 | 2-100 |
10 | 10000 | 1000 | 156 | 999 | 2-100 |
Внешняя нагрузка (играющий Winamp) | |||||
100 | 10000 | 100 | 97 | 100 | 28-51 |
15 | 10000 | 667 | 175 | 632 | 100 |
10 | 10000 | 1000 | 22 | 894 | 100 |
Специально для
Исходные тексты программ, приложенные к данной статье, распространяются на правах freeware.
Все исходные тексты и откомпилированная DLL собраны в архив .
Тестовая программа (исходные тексты) отдельно в файле
Для интересующихся - сорцы версии на С++ в файле .