Измерение времени выполнения

Тема в разделе "WASM.SOFTWARE", создана пользователем SloT, 15 авг 2008.

  1. SloT

    SloT New Member

    Публикаций:
    0
    Собственно может кто-то знает программы или функции для измерения выполнения программы или куска кода?
    Знаю функцию GetTickCount, но не знаю, как её оформить. Покажите пожалуйста на примере.
    Если кто поможет, то тому спасибо)))
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Режим какой и какая точность нужна ?
     
  3. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
  4. nobodyzzz

    nobodyzzz New Member

    Публикаций:
    0
    Код (Text):
    1. DWORD ticks = GetTickCount();
    2. ..code
    3. ticks = GetTickCount() - ticks;
    =)
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Нафиг она нада, обновление каждую миллисекунду, что этим замеришь.
     
  6. zhivoder

    zhivoder Nikolay

    Публикаций:
    0
    Самое путёвое это использовать rdtsc. Эта шняга возвращает значение счетчика тактов процессора в EDX:EAX(64бита). Надо сначала узнать значение, выполнить нужный код, и снова узнать значение. это более или менее точно ;)для БОльшей точности приложив моск можно ещё учесть такты на выполнение самой этой команды и тогда макс. точность обеспечена...
     
  7. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    ТСК мёртв. При каждом тике таймера апик(делитель 1) инкрементируется значение поля в KPRKB. Это счётчик числа прерываний профилирования. Можем мы спроецировать часть ядерной памяти в юзермодное АП, страницу KPCR, её адрес физический мы знаем 0x40000. Двумя последовательными чтениями счётчика тиков в проекции ядерной памяти по смещению InterruptCount считаем мы дельту, скоректируем её в зависимости от производительности системы(поле ProfileScaleFactor) мы получим время исполнения кода.
    Также повысив перед этим потока приоритет и значение взяв минимальное из множества циклов чтения, исключив тем фактор планирования.
    Смещения в относительно страницы KPCR для SP2 знаем:
    InterruptCount = 0x5С4
    ProfileScaleFactor = 0x98
     
  8. zhivoder

    zhivoder Nikolay

    Публикаций:
    0
    Это какое то извращение. Во-первых с какого ИКСа ТСК умер.?. Он даже нее болел. Во-вторых, зачем наживать себе лишний геморрой если ответ плавает на поверхности?
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Кристалег не обижаецца :)
    Потестил. Результат нормальный.
     
  10. SloT

    SloT New Member

    Публикаций:
    0
    всем спасибо, буду пробовать =)
     
  11. SloT

    SloT New Member

    Публикаций:
    0
    с GetTickCount и с QueryPerformanceCounter разобрался)))
    CrystalIC
    то, о чём ты написал, к сожалению, мне не очень понятно, но буду рад узнать что-то новое, если ты объяснишь подробнее или укажешь, где почитать(желательно на русском).
    З.Ы. QueryPerformanceCounter точнее, чем GetTickCount.
     
  12. SloT

    SloT New Member

    Публикаций:
    0
    zhivoder
    что такое rdtsc?
    Поясни пожалуйста.
     
  13. Nero_n

    Nero_n New Member

    Публикаций:
    0
    rdtsc - read time stamp counter. инструкция процессора такая.

    к стате, разве Clerk != CristalIC?
     
  14. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    SloT
    QueryPerformanceCounter() к rdtsc сводится(QueryPerformanceCounter -> NtQueryPerformanceCounter -> KeQueryPerformanceCounter -> HalQueryPerformanceCounter. Читает тойже rdtsc.)
    QueryPerformanceCounter быть точнее GetTickCount не может, первая юзает смену кольца и rdtsc.
    GetTickCount никакой сервис не вызывает, читая значение из разделяемой ядром памяти. Сервис этот выполняется быстрее чем 1ms, а значение числа тактов в разделяемой памяти меняется один раз за 1ms.
    Просто всё, из юзермода доступна ядерная память, к примеру отобразив на юзермодное пространство переменную нтоса KeTickCount, это значение будет меняться с частотой 1 kHz, нам просто надо его считать из памяти инструкцией. Та область памяти(начиная с PCR(Processor control block) содержит многие счётчики, память невыгружаемая, значит и адрес физический фиксирован. Остаётся спроецировать.
    Как ктото недавно сказал - несколько миллиардов итераций, на которые уйдёт значительное время и для тск точность можно считать достаточной, это - извращение.
     
  15. zhivoder

    zhivoder Nikolay

    Публикаций:
    0
    Это привелегированая инструкция процессора, вызывается без параметров, записывает в EDX:EAX текущее значение счётчика тактов процессора. С помощью этой команды можно организовать самый точный метод измерения относительного времени выполнения кода(ну если находиться на ring0). если код проверять в какой либо ОС, то там встретятся заморочки с переходами ring3->ring0 и т.д. и т.п.
     
  16. leo

    leo Active Member

    Публикаций:
    0
    Мда, накуролесили :)
    1) rdtsc в винде - это не привелегированная инструкция (ее можно сделать привелегированной, установив флаг TSD в CR4, но эту фишку юзают только антиотладочные плагины типа Phantom, Olly Advanced и т.п.). Поэтому юзать rdtsc из юзермода можно без проблем (см. А.Фога, + поиск wintest.exe здесь на форуме)
    2) QueryPerformance не на всех тачках сводится к rdtsc (также могут юзаться мм-таймеры высокого разрешения в несколько мкс)
    3) Для измерения с точностью до 1мс не обязательно лезть в ring0, т.к. в юзермоде можно юзать timeBeginPeriod\timeEndPeriod и мерить время timeGetTime (причем изменение интервала через timeBeginPeriod может также сказываться и на повышении точности GetTickCount)
     
  17. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    leo
    1. Конечно, даже юзается из ntdll.RtlpWaitForCriticalSection.
    2. HalQueryPermormanceCounter юзает rdtsc, ни к каким высокоточным таймерам не обращается(за исключением инициализации PIT).
    3. Попробуй.
     
  18. SloT

    SloT New Member

    Публикаций:
    0
    вот теперь понятно, всем огромное спасибо =)
     
  19. leo

    leo Active Member

    Публикаций:
    0
    CrystalIC
    2. В win98 не юзает :) Если ты демонстрируешь познания потрохов винды и предлагаешь юзать физ.адреса и смещения ядерной памяти, то не мешало бы оговорить для каких версий винды все это рулит. И для висты, и для серверов, и для 64-битных ?
    3. Не пробовал бы - не говорил ;) Возможность изменения интервала для timeGetTime документировано, а то, что оно влияет и на GetTickCount - видел своими глазами в XP SP2 (реал-тайм приоритет, под админом), но поскольку я подробно это дело не копал, то и говорю "может влиять". Если ты прольешь свет на механизм работы timeBeginPeriod - скажу спасибо, пригодиться для общего развития ;)
    PS: То, что число системных тиков всегда меняется с частотой 1КГц у меня лично вызывает сомнения - откуда тогда берется дробное значение интервала 15.625 мс, и нафига самой винде нужно так часто считать тики ? Может просто на твоей тачке какая прога\сервис устанавливает интервал в 1мс для мультимедийных прибамбасов ?
     
  20. CrystalIC

    CrystalIC New Member

    Публикаций:
    0
    leo
    Ничего я не демонстрирую, говорю как делал бы я. Вобщем я так понял что в пустоту говорю.
    98, 3.1 и остальных такого тапа не знаю как будет, SP1, SP2, SP3, Vista это будет работать. Для 32-х разрядных.
    На скока помню timeBeginPeriod сводится к NtSetTimerResolution.
    Аппаратные прерывания от таймеров вызываются очень часто(KeUpdateSystemTime), 1kHz это один из счётчиков, и определяется реальной частотой прерываний делённой на константу.
    Посмотри сам. http://openfile.ru/72697/