Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.141.199.243] |
|
Сообщ.
#1
,
|
|
|
Измерение скорости выполнения куска кода Итак, процессоры Pentium и выше имеют внутренний 64-битный счётчик тактов, изменяющийся с частотой, равной тактовой частоте процессора. Этот счётчик может быть прочитан с помощью инструкции rdtsc, при этом значение записывается в регистры edx:eax (edx содержит старшу часть). Т.о, прочитав это значение перед выполнением определённого кода и после, можно узнать сколько тактов процессора потребовалось для обработки этого кода. Для этого нужно лишь вычесть первое значение и кол-во тактов, необходимое для выполнения служебных инструкций (типа rdtsc). Ну, и конечно, желательно сделать программу так, чтобы учитывались особенности современных процессоров. Большая часть программы тестирования скорости выполнения кода (приведённая ниже) взята из документации по оптимизация кода для процессоров Pentium Agner'а Fog'а. Результаты выводятся в виде 16-ричных чисел! ; 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 Если Вы хотите использовать код в Windows-проложениях, не забудьте заменить регистр bx на ebx, определение Pointer dw на Pointer dd и изменить блок вывода результатов (т.к. int 29h под Windows предназначен явно не для вывода символов). |