I'm trying to time a subroutine using rdtscp. This is my procedure:
; Setting up time
rdtscp ; Getting time
push rax ; Saving timestamp
; for(r9=0; r9<LOOP_SIZE; r9++)
mov r9, 0
lup0:
call subr
inc r9
cmp r9, LOOP_SIZE
jnz lup0
; Calculating time taken
pop rbx ; Loading old time
rdtscp ; Getting time
sub rax, rbx ; Calculating difference
if LOOP_SIZE
is small enough, I get consistent and expected results. However, when I make it big enough (around 10^9) I spike from 10^9 to 10^20.
; Result with "LOOP_SIZE equ 100000000"
971597237
; Result with "LOOP_SIZE equ 1000000000"
18446744072281657066
The method that I'm using to display the numbers displays them as unsigned, so I imagine that the large number displayed is actually a negative number and an overflow happened. However, 971597237
is not even close to the 64 bit integer limit, so, assuming that the problem is an overflow, why is it happening?
rdtsc
annoyingly puts its result in EDX:EAX even in 64-bit mode. felixcloutier.com/x86/rdtsc. You're only saving / using the low 32 bits of the TSC, and getting a 32-bit unsigned difference, sign-extended to 64-bit because you're computing it withsub rax, rbx
on the zero-extended 32-bit values instead ofsub eax, ebx
. – Peter Cordes