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.
Balala
É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 |
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); } |