RDTSC

Ami engem elsősorban érdekelne, az az, hogy hogyan mértek órajelet. Jó, RDTSC, de azért az annyira nem egyszerű, az RDTSC-nek is van ideje, plusz a regisztereket is el kell menteni, stb. szóval nem egészen triviális.

Én az általad is sokat emlegetett Agner Fog féle doksi alapján mértem előszőr pontos értékeket.

Itt a teljes mérő rutinom:
.586

B EQU BYTE PTR
W EQU WORD PTR
D EQU DWORD PTR
Q EQU DWORD PTR
O EQU OFFSET

LOCALS

ITER    EQU     6

RDTSC   MACRO
        DB 0FH,31H
ENDM

_TEXT   SEGMENT BYTE PUBLIC USE32 'CODE'
    ASSUME  CS:_TEXT, DS:DGROUP

PUBLIC MAINASM
MAINASM:
                finit

                MOV     [COUNTER],0
TESTLOOP:
                LEA     ESI,COUNTER          ; L1 cache clear
                MOV     ECX,8192/32
@@0:
                MOV     EAX,[SI]
                ADD     ESI,32
                DEC     ECX
;               JNZ     @@0
;------------------------------------------------------------------------- init
                FLD1
;------------------------------------------------------------------------------
                RDTSC
                MOV     [TICS],EAX
                CLD
        REPT 8
                NOP
        ENDM
;------------------------------------------------------------------------ rutin
                FLD     ST
;               FCOMP ST
;------------------------------------------------------------------------------
                CLC
                RDTSC
                SUB     EAX,[TICS]
                SUB     EAX,16
                MOV     EDX,[COUNTER]
                MOV     [RESULTLIST][EDX],EAX
;----------------------------------------------------------------------- deinit
        FCOMP ST
        FCOMP ST
;        FCOMP ST
;        FCOMP ST
;        FCOMP ST
;------------------------------------------------------------------------------
                ADD     EDX,TYPE RESULTLIST
                MOV     [COUNTER],EDX
                CMP     EDX,ITER * (TYPE RESULTLIST)
                JB      TESTLOOP
;------------------------------------------------------------------------------
KIIRAS:
                PUSH    -ITER
                POP     ESI
@@0:
                MOV     EAX,[ ESI*4 + RESULTLIST + ITER * (TYPE RESULTLIST) ]
;------------------------------------------------------------------------------
                PUSH    10
                SUB     ECX,ECX
                POP     EBP
@@1:
                SUB     EDX,EDX
                DIV     EBP
                PUSH    EDX
                INC     ECX
                TEST    EAX,EAX
                JNZ     @@1
@@2:
                POP     EDX
                ADD     DL,'0'
                MOV     AH,2
                INT     21H
                DEC     ECX
                JNZ     @@2
;------------------------------------------------------------------------------
                MOV     DL,13
                MOV     AH,2
                INT     21H
                MOV     DL,10
                MOV     AH,2
                INT     21H
                INC     ESI
                JNZ     @@0
;------------------------------------------------------------------------------
                RETN
;------------------------------------------------------------------------------
_TEXT   ENDS
DGROUP GROUP _DATA,_BSS
_DATA   SEGMENT PARA PUBLIC USE32 'DATA'
_DATA   ENDS
_BSS    SEGMENT DWORD PUBLIC UNINIT USE32 'BSS'
COUNTER         DD      ?
TICS            DD      ?
RESULTLIST      DD      ITER DUP(?)
                DB      8160 DUP(?)
_BSS    ENDS
    END
Ha pontosan működik, akkor ezt az 1 db FLD ST utasítást 1 gépi ciklusnak méri le.

WatcomC-ben szoktam használni egy másik rutint is, ami jóval egyszerűbb, de némi kisérletezés után kiszámíthatjuk azt konstanst, ami esetleg a 14-es helyére kellhet.

void main (void) {
double tic;

double RDTSC(void);
#pragma aux RDTSC value [8087] modify [EAX EDX]=\
"               DB 0FH,31H          "\
"               PUSH EDX            "\
"               PUSH EAX            "\
"               FILD QWORD PTR [ESP]"\
"               POP EAX             "\
"               POP EDX             "

 tic=RDTSC();
 // a lemerendo rutin helye
 tic=RDTSC()-tic-14;

 printf("%g",tic);

}