Собственно может кто-то знает программы или функции для измерения выполнения программы или куска кода? Знаю функцию GetTickCount, но не знаю, как её оформить. Покажите пожалуйста на примере. Если кто поможет, то тому спасибо)))
Самое путёвое это использовать rdtsc. Эта шняга возвращает значение счетчика тактов процессора в EDX:EAX(64бита). Надо сначала узнать значение, выполнить нужный код, и снова узнать значение. это более или менее точно для БОльшей точности приложив моск можно ещё учесть такты на выполнение самой этой команды и тогда макс. точность обеспечена...
ТСК мёртв. При каждом тике таймера апик(делитель 1) инкрементируется значение поля в KPRKB. Это счётчик числа прерываний профилирования. Можем мы спроецировать часть ядерной памяти в юзермодное АП, страницу KPCR, её адрес физический мы знаем 0x40000. Двумя последовательными чтениями счётчика тиков в проекции ядерной памяти по смещению InterruptCount считаем мы дельту, скоректируем её в зависимости от производительности системы(поле ProfileScaleFactor) мы получим время исполнения кода. Также повысив перед этим потока приоритет и значение взяв минимальное из множества циклов чтения, исключив тем фактор планирования. Смещения в относительно страницы KPCR для SP2 знаем: InterruptCount = 0x5С4 ProfileScaleFactor = 0x98
Это какое то извращение. Во-первых с какого ИКСа ТСК умер.?. Он даже нее болел. Во-вторых, зачем наживать себе лишний геморрой если ответ плавает на поверхности?
с GetTickCount и с QueryPerformanceCounter разобрался))) CrystalIC то, о чём ты написал, к сожалению, мне не очень понятно, но буду рад узнать что-то новое, если ты объяснишь подробнее или укажешь, где почитать(желательно на русском). З.Ы. QueryPerformanceCounter точнее, чем GetTickCount.
SloT QueryPerformanceCounter() к rdtsc сводится(QueryPerformanceCounter -> NtQueryPerformanceCounter -> KeQueryPerformanceCounter -> HalQueryPerformanceCounter. Читает тойже rdtsc.) QueryPerformanceCounter быть точнее GetTickCount не может, первая юзает смену кольца и rdtsc. GetTickCount никакой сервис не вызывает, читая значение из разделяемой ядром памяти. Сервис этот выполняется быстрее чем 1ms, а значение числа тактов в разделяемой памяти меняется один раз за 1ms. Просто всё, из юзермода доступна ядерная память, к примеру отобразив на юзермодное пространство переменную нтоса KeTickCount, это значение будет меняться с частотой 1 kHz, нам просто надо его считать из памяти инструкцией. Та область памяти(начиная с PCR(Processor control block) содержит многие счётчики, память невыгружаемая, значит и адрес физический фиксирован. Остаётся спроецировать. Как ктото недавно сказал - несколько миллиардов итераций, на которые уйдёт значительное время и для тск точность можно считать достаточной, это - извращение.
Это привелегированая инструкция процессора, вызывается без параметров, записывает в EDX:EAX текущее значение счётчика тактов процессора. С помощью этой команды можно организовать самый точный метод измерения относительного времени выполнения кода(ну если находиться на ring0). если код проверять в какой либо ОС, то там встретятся заморочки с переходами ring3->ring0 и т.д. и т.п.
Мда, накуролесили 1) rdtsc в винде - это не привелегированная инструкция (ее можно сделать привелегированной, установив флаг TSD в CR4, но эту фишку юзают только антиотладочные плагины типа Phantom, Olly Advanced и т.п.). Поэтому юзать rdtsc из юзермода можно без проблем (см. А.Фога, + поиск wintest.exe здесь на форуме) 2) QueryPerformance не на всех тачках сводится к rdtsc (также могут юзаться мм-таймеры высокого разрешения в несколько мкс) 3) Для измерения с точностью до 1мс не обязательно лезть в ring0, т.к. в юзермоде можно юзать timeBeginPeriod\timeEndPeriod и мерить время timeGetTime (причем изменение интервала через timeBeginPeriod может также сказываться и на повышении точности GetTickCount)
leo 1. Конечно, даже юзается из ntdll.RtlpWaitForCriticalSection. 2. HalQueryPermormanceCounter юзает rdtsc, ни к каким высокоточным таймерам не обращается(за исключением инициализации PIT). 3. Попробуй.
CrystalIC 2. В win98 не юзает Если ты демонстрируешь познания потрохов винды и предлагаешь юзать физ.адреса и смещения ядерной памяти, то не мешало бы оговорить для каких версий винды все это рулит. И для висты, и для серверов, и для 64-битных ? 3. Не пробовал бы - не говорил Возможность изменения интервала для timeGetTime документировано, а то, что оно влияет и на GetTickCount - видел своими глазами в XP SP2 (реал-тайм приоритет, под админом), но поскольку я подробно это дело не копал, то и говорю "может влиять". Если ты прольешь свет на механизм работы timeBeginPeriod - скажу спасибо, пригодиться для общего развития PS: То, что число системных тиков всегда меняется с частотой 1КГц у меня лично вызывает сомнения - откуда тогда берется дробное значение интервала 15.625 мс, и нафига самой винде нужно так часто считать тики ? Может просто на твоей тачке какая прога\сервис устанавливает интервал в 1мс для мультимедийных прибамбасов ?
leo Ничего я не демонстрирую, говорю как делал бы я. Вобщем я так понял что в пустоту говорю. 98, 3.1 и остальных такого тапа не знаю как будет, SP1, SP2, SP3, Vista это будет работать. Для 32-х разрядных. На скока помню timeBeginPeriod сводится к NtSetTimerResolution. Аппаратные прерывания от таймеров вызываются очень часто(KeUpdateSystemTime), 1kHz это один из счётчиков, и определяется реальной частотой прерываний делённой на константу. Посмотри сам. http://openfile.ru/72697/