" title="Написать письмо">Написать письмо

Статистика

Пользователи : 1
Статьи : 2467
Просмотры материалов : 10508226
 
Относительность тестов длительности кода (01.09.2026). Печать E-mail
2026 - Сентябрь
01.09.2026 04:38
Save & Share
Все нормальные дети отсыпаются перед 1 сентября - нет, одного ночью на нефатальность мира потянуло. Есть какой-то участок исходного кода (нужно выбрать самый быстрый способ генерации мусора) - надо протестировать на скорость, глаза и мозги в роли наблюдателей. И понеслась...


Почему люблю Borland и ненавижу Qt. В Borland механизм подсчёта времени представлен в виде функций вычисления некоей частоты QueryPerformanceFrequency и некоих тиков QueryPerformanceCounter. В Qt есть просто таймер QElapsedTimer, который может в start, restart, получение значения в микросекундах и наносекундах. И вот именно разделение на 2 части таймера - позволяет истинно понять, что таймер точно работает, - и как работает.

Переведённая справка по QElapsedTimer:
"
Опорные часы

На всех платформах, поддерживающих монотонные часы (см. QElapsedTimer::isMonotonic()), QElapsedTimer использует именно этот тип опорных часов. Преимущество такого подхода заключается в том, что на работу QElapsedTimer не влияют корректировки времени, выполняемые, например, пользователем. Кроме того, в отличие от QTime, QElapsedTimer не зависит от изменений настроек часового пояса или перехода на летнее время.

С другой стороны, это означает, что значения QElapsedTimer можно сравнивать только с другими значениями, полученными с использованием того же источника отсчета. Это особенно важно, если время, прошедшее с момента начала отсчета, извлекается из объекта QElapsedTimer (метод QElapsedTimer::msecsSinceReference()) и сериализуется. Такие значения не следует передавать по сети или сохранять на диске, поскольку невозможно гарантировать, что компьютер, принимающий данные, совпадает с тем, который их отправил, или что принимающий узел не был перезагружен в промежутке между этими событиями.

Тем не менее, обмен такими значениями возможен между процессами, запущенными на одном и том же компьютере, при условии, что они используют те же опорные часы. Поскольку QElapsedTimer всегда использует один и тот же источник времени, сравнение со значением, полученным от другого процесса на той же машине, безопасно. При сравнении со значениями, полученными с помощью других API, необходимо убедиться, что используемый источник времени совпадает с тем, который задействует QElapsedTimer (см. QElapsedTimer::clockType()).
"
.

Монотонные часы... Сериализация времени... Ещё и другие таймеры Qt мешают осознанию реальности (QChronoTimer, QDeadlineTimer). Точно, ну его на...

Эксперименты в билдере были простыми. QueryPerformanceFrequency выводилась в Caption формы в 2 вариантах: простой ЦП (1.2ГГц) и его загрузка (2.5ГГц) - контроль с помощью HWiNFO. В обоих случаях в виртуальной машине с Windows XP SP2 x32 было получено одинаковое значение: 3.579.545. Значит, это не частота ЦП - а частота независимого таймера HPET (и тики тоже от него берутся - то есть, полная отвязка от хаотичности частот ЦП - реальное время с некоторым постоянным дискретом).

Из этого следует, что именно девиация частоты ЦП (колебания без разгона, сам разгон) влияют на хаотичность получаемого времени при тестировании кода. И чем меньше время теста - тем больше они влияют на конечный результат (поэтому короткий во времени исходный код рекомендуется циклить в for и считать среднее арифметическое).

Но тут в родительской Windows 7 x64 QueryPerformanceFrequency показывает число 2.441.455. Ну, ладно, просто: HPET виртуальной материнской платы VirtualBox отличается от HPET реальной материнской платы (но почему меньше-то?). Для этого грузится виртуальная машина с точно такой же ОС - на выходе получается... 10млн на том же виртуальном чипсете... Третья виртуалка с WinPE - 10млн. Какого х...

Оказывается, тип виртуальной машины (где ОС при её создании выбирается) - напрямую влияет на настройки материнской платы (вплоть до незагрузки ОС после изменения) - это влияет и на частоту. Обратное доказательство: загрузка с WinPE x32 в разных выборах ОС (x32, x64).

Далее на Windows 7 x32 получено число 3.579.545, как у XP x32. А это не HPET нихрена, а ACPI Power Management Timer с фиксированной частотой. А есть ещё Programmable Interval Timer и Real-Time Clock - отсюда и странное значение 2.44МГц для родительской ОС. При этом, ИИ гугла пестрит о том, что HPET в Windows 7 активно используется, - а вон оно как (при условии, что он включён в BIOS).

Далее был эксперимент с одной и той же виртуалкой с выбором ОС "Windows XP x64": Windows 10 x32 - 2.441.395, Windows 8 x32 - 2.441.461, Windows 8 x32 Native - 2.441.413. Поменял на "Windows 10 x64": Windows 10 x32 - 2.441.412, Windows 8 x32 - 2.441.412, Windows 8 x32 Native - 2.441.412. Выключил виртуалку, снова включил: Windows 8 x32 Native - 2.441.412. Ладно, от старта-выключения не зависит - но какого хрена числа одинаковые. А потом на "Windows 10 x64" и "Windows XP x64" загрузил одну и ту же Windows 10 x64: 10МГц - да бл...

Что получается. В большинстве случаев, именно в старых ОС (а не в старом оборудовании) - страдает точность вычислений. Если в Qt под Windows XP x32 выбрать наносекундные показания в QElapsedTimer - разработчиков этой среды можно сажать на кол: возникнет погрешность 279нс при каждой секунде работы, и среда разработки об этом вообще ничего не скажет - а погрешности даже 10-19 могут быть критичными. И что они сделали: тупо ответственность с себя сняли огромной простынёй в начале статьи - а не описали конкретные примеры работы. С билдером же всё предельно ясно: на тебе текущую частоту - текущую точность ты теперь вычислишь - развлекайся.

Страдает лишь точность измерения времени: все устройства его измерения работают на своих частотах на аппаратном уровне. Далее вступают в силу плавание частоты логических процессоров CPU, логика работы функции разгона и торможения, особенности ОС и т.д. Именно поэтому важны миллионы и миллиарды прогонов простых участков кода: интересные вещи вырисовываются.

Вообще, материал должен был быть немного другой, - но не получилось.
Обновлено ( 01.09.2026 08:21 )
 
 

Последние новости


©2008-2026. All Rights Reserved. Разработчик - " title="Сергей Белов">Сергей Белов. Материалы сайта предоставляются по принципу "как есть". Автор не несет никакой ответственности и не гарантирует отсутствие неправильных сведений и ошибок. Вся ответственность за использование материалов лежит полностью на читателях. Размещение материалов данного сайта на иных сайтах запрещено без указания активной ссылки на данный сайт-первоисточник (ГК РФ: ст.1259 п.1 + ст.1274 п.1-3).

Много статей не имеет срока устаревания. Есть смысл смотреть и 2011, и даже 2008 год. Политика сайта: написать статью, а потом обновлять ее много лет.
Рекламодателям! Перестаньте спамить мне на почту с предложениями о размещении рекламы на этом сайте. Я никогда спамером/рекламщиком не был и не буду!
Top.Mail.Ru