" title="Написать письмо">Написать письмо
На выжить после операций проктологии
2200 4002 2461 6363

Статистика

Пользователи : 1
Статьи : 2533
Просмотры материалов : 10957134
 
Об измерении времени выполнения исходников (04.11.2026). Печать E-mail
2026 - Ноябрь
04.11.2026 09:07
Save & Share
Не знаю, зачем пишу этот материал: его может знать каждый школьник среднего развития, у которого было программирование с 8 класса. Когда в 13 лет мне пришлось выполнить задание (написать программу, показывающую мультик на экране: взрыв в зоне отдыха ядерной бомбы), - на QBasic возникли проблемы производительности, по причине наличия в классе устаревших ПК x86. Тогда всё решил внутренней оптимизацией кода, без анализа, на уровне интуиции. Но мозги уже поняли: будешь кодить плохо - будешь потом исправлять - мысли о необходимости тестирования исходников численно на скорость были уже заложены.


Если с выпускниками 2002 года это было абсолютно очевидным (а ведь класс был не с уклоном на информатику, а физмат, - информатика там была как кобыле хвост: БУП-98 - распространялся на все классы). То сейчас с выпускниками вузов, даже по сильной специальности "программная инженерия", наблюдается ерунда: они ничего не знают не просто об измерении времени кода - но и о его особенностях, и вообще программировать не могут. Последний стажёр в этом году: все курсовые за него писал AI (сейчас и у родителей школьных мальков проблема: как им объяснить, что надо учиться, - если всё может сделать AI). Он вообще в программировании ничего не знал (хотя утверждал обратное). Придумал для него тесты: давал ему 4 задачи, состоящие из 2-4 строчек кода (при условии, что они уже написаны, - ускорь/объясни/докажи/исправь). Одна задачка - частично правильно (но неизвестно, делал он её сам или AI), вторая (очно, с телефоном именно в кармане) - провал из-за незнания определений, третья и четвёртая (тоже очно) - самостоятельный провал. Он не смог загуглить 2 функции (которые будут ниже описаны), прочитать по ним короткую справку и ответить на вопрос: какая размерность предоставляемой информации (при этом, пришлось объяснять ещё, что такое размерность).

Получается, я пишу этот материал для молодняка? А он точно поймёт, что тут написано? Morituri sumus...

QueryPerformanceCounter:
- стандартная функция Windows API, читающая из материнской платы, из отдельного аппаратного счётчика HPET, чёткое количество тиков процессора с момента старта ПК;
- если быть злорадным и выключить HPET в BIOS (чтобы игрульки быстрее работали) - функция начнёт обращаться к другим счётчикам в ОС, программным типа TSC/QPC/ACPI/гипервизора, - давая при этом менее точный результат;
- может находиться в разных H-файлах (Windows.h, profileapi.h). Может называться другими словами (как Qt выдумала свои QString, QInt и т.д. - когда сравнивая их с обычными типами, скорость одна и та же) - но это лишь функция-обёртка для этой системной функции;
- в Linux, Mac и иных ОС - может иметь другое название (например, clock_gettime);
- алгоритм использования: измерить количество тиков до старта исходного кода, измерить количество тиков после окончания исходного кода - и вычесть одно из другого (ну какой же детский сад, а...).

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

Если бы современные стажёры хоть немножко программировали на практике - жизнь бы по-любому их столкнула лбом с измерениями времени. Но если не смотреть на вопрос трудолюбия, усидчивости и IQ - к функциям есть вопросы, которые нормальные стажёры образца до 2016 года могут и не знать. Связаны они исключительно с аппаратными неточностями реального мира, технологиями изготовления и внимательностью программиста:
- частота ЦП постоянно плавает не только потому, что его таким создали. Есть обращающиеся к нему фоновые процессы ОС, технологии энергосбережения (из которых надо потратить время, чтобы выйти), разгон автоматический типа Turbo Boost (который тоже не мгновенен), использование внутренних технологий и инструкций ЦП и т.д. На протяжение всего времени выполнения исходного кода, тики увеличиваются с нелинейными девиациями. В результате, чем меньше время выполнения исходного кода, и чем больше фоновых или иных отвлекающих ЦП процессов, - тем больше будет погрешность измерения, вплоть до полного неликвида;
- при получении с помощью QueryPerformanceFrequency частоты процессора - получается именно текущая частота, какая-то из плавающих (в какой момент её получать - не имеет значения: не избежать потери точности);
- сама логика измерения времени содержит неисправимый баг. Где бы ни находилось в функции QueryPerformanceCounter получение прям текущих тиков - в расчётное время попадёт одно время выполнения её самой. При ультраточных расчётах (специально попробовал на удельном времени обработки данных 0.5нс/Б) - время "выполнения" исходного кода показало в 20 раз больше. Когда программист знает такую особенность - он лишь усмехнётся, а не пойдёт по ложному пути (но от разницы, всё-таки, охренеет);
- чтобы избежать искажений, требуются множественные измерения и среднее арифметическое - независимо от времени работы стандартного исходного кода. Чтобы убить простую и крупную девиации, первую + вторую: минимальное число за практику - 1000. Если речь о нестандартном коде, когда необходимо убить и третью неточность, - используются многомиллионные числа в цикле не потому, что можно из-за чрезмерно малого времени выполнения кода, - а потому что нужно размазать время выполнения QueryPerformanceFrequency. Максимальное используемое число на практике - 4294967295 (иногда даже тесты приходилось оставлять на ночь);
- при нестандартном быстром исходном коде - сам цикл for начинает искажать истинное значение в большую сторону (особенно, если число не константа, а медленный тип данных). Решается просто: тестируется на время сам цикл - и это время вычитается из основного или промежуточного результата. В моём случае, размазывание и этого времени по 400млн измерений ничего не даёт, естественно, - забыл про это свойство - 1.9% времени он всё-таки прибавлял.
Обновлено ( 04.11.2026 12:25 )
 
 

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


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

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