На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! Перед отправкой сообщения внимательно прочтите правила раздела!!!
1. Все статьи должны быть оформлены согласно Правил оформления статей.
2. Любые обсуждения должны происходить в специальной теме, обсуждение в любых других темах раздела запрещены.
3. Запрещается писать статьи о создании и распространении вирусов, троянов и других вредоносных программ!
4. За грамотно написанные и правильно оформленные статьи авторы награждаются DigiMoney.

Дополнительные ссылки:
Желаю творческих успехов! ;)
Модераторы: Jin X
  
    > Измерение скорости выполнения куска кода , Zen
       
      Измерение скорости выполнения куска кода

      Итак, процессоры Pentium и выше имеют внутренний 64-битный счётчик тактов, изменяющийся с частотой, равной тактовой частоте процессора. Этот счётчик может быть прочитан с помощью инструкции rdtsc, при этом значение записывается в регистры edx:eax (edx содержит старшу часть). Т.о, прочитав это значение перед выполнением определённого кода и после, можно узнать сколько тактов процессора потребовалось для обработки этого кода. Для этого нужно лишь вычесть первое значение и кол-во тактов, необходимое для выполнения служебных инструкций (типа rdtsc). Ну, и конечно, желательно сделать программу так, чтобы учитывались особенности современных процессоров.

      Большая часть программы тестирования скорости выполнения кода (приведённая ниже) взята из документации по оптимизация кода для процессоров Pentium Agner'а Fog'а. Результаты выводятся в виде 16-ричных чисел!
      ExpandedWrap disabled
        ; tasm /m spdtest.asm
        ; tlink /t /x spdtest.asm
         
        .MODEL Tiny
        .586P
         
        Repeat      =   1              ; Сколько кусков тестового кода подряд
        TestLoops   =   10             ; Сколько циклов
        Debug       =   0              ; 0=вставлять "cli"
         
        rdtsc       macro
                db  0Fh,31h
        endm
         
        .CODE
        ORG 100h
         
        Start:
         
        ife     Debug
                cli                    ; Запрещаем прерывания (IRQ)
        endif
         
                rdtsc
                push    eax            ; Получаем первое значение счётчика
         
                cld                    ; < что
                rept    8              ; < это
                nop                    ; < такое
                endm                   ; < смотрите
                clc                    ; < ниже
         
                rdtsc                  ; Получаем второе значение счётчика
                pop edx
                sub eax,edx        ; Вычисляем время служебных инструкций
                mov Overhead,eax   ; Сохраняем его в переменной
         
        TestLoop:
        ;----------------------------------------------------------;
                        ; Сюда вставить инициализацию ;
        ;----------------------------------------------------------;
         
                rdtsc
                push    eax            ; Получаем первое значение счётчика
         
                cld                    ; Неспариваемая инструкция
                rept    8
                nop                    ; Предотвращение эффекта тени
                endm
         
                rept    Repeat
        ;----------------------------------------------------------;
                        ; Сюда вставить тестовый код ;
        ;----------------------------------------------------------;
                endm
         
                clc                    ; Неспариваемая инструкция
         
                rdtsc                  ; Получаем второе значение счётчика
                pop edx
                sub eax,edx        ; Вычисляем время выполнения...
                sub eax,Overhead   ; ...тестового кода
         
                mov bx,Pointer
                mov [bx],eax       ; Сохраняем значение в массиве Ticks
                add bx,4
                mov Pointer,bx
                cmp bx,offset Ticks+TestLoops*4
                jb  TestLoop       ; Повторяем тест, если необходимо
         
        ;-- Вывод результатов -------------------------------------;
         
                lea bx,Ticks
        ShowDWord:
                mov edx,[bx]       ; Получаем значение из массива Ticks
                mov cl,28
        @@NextDigit:    ror edx,cl
                mov al,dl
                and al,0Fh
                add al,'0'
                cmp al,'9'
                jbe @@09
                add al,'A'-('9'+1) ; Преобразуем в 16-ричный вид...
        @@09:       int 29h            ; ...и выводим
                rol edx,cl
                sub cl,4
                jnc @@NextDigit
                mov al,13          ; CR
                int 29h
                mov al,10          ; LF (новая строка)
                int 29h
         
                add bx,4
                cmp bx,offset Ticks+TestLoops*4
                jb  ShowDWord      ; Повторяем вывод, если необходимо
         
        ife     Debug
                sti                    ; Разрешаем прерывания (IRQ)
        endif
         
                int 20h            ; Выходим из программы
         
        ;-- Данные ------------------------------------------------;
         
        Pointer     dw  Ticks
        Ticks       dd  TestLoops dup (?)
        Overhead    dd  ?              ; Время служебных инструкций
         
        END     Start
      Хочу сразу заметить, что в данной программе используется только значение регистра eax, возвращаемое инструкцией rdtsc, поэтому с её помощью нельзя измерять участки кода длительностью более ~ 4 млрд. тактов.
      Если Вы хотите использовать код в Windows-проложениях, не забудьте заменить регистр bx на ebx, определение Pointer dw на Pointer dd и изменить блок вывода результатов (т.к. int 29h под Windows предназначен явно не для вывода символов).
      0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0186 ]   [ 15 queries used ]   [ Generated: 26.04.24, 21:15 GMT ]