使用RDTSC测量时差-结果太大

Pio*_*rek 1 c linux x86 assembly att

我正在尝试计算运行单个ASM指令所需的CPU周期数。为了做到这一点,我创建了这个函数:

measure_register_op:
    # Calculate time of required for movl operation

    # function setup
    pushl %ebp
    movl %esp, %ebp
    pushl %ebx
    pushl %edi

    xor %edi, %edi

    # first time measurement
    xorl %eax, %eax
    cpuid               # sync of threads
    rdtsc               # result in edx:eax

    # we are measuring instuction below
    movl %eax, %edi     

    # second time measurement
    cpuid               # sync of threads
    rdtsc               # result in edx:eax

    # time difference
    sub %eax, %edi

    # move to EAX. Value of EAX is what function returns
    movl %edi, %eax

    # End of function
    popl %edi
    popl %ebx
    mov %ebp, %esp
    popl %ebp

    ret
Run Code Online (Sandbox Code Playgroud)

我在* .c文件中使用它:

extern unsigned int measure_register_op();

int main(void)
{

    for (int a = 0; a < 10; a++)
    {
        printf("Instruction took %u cycles \n", measure_register_op());
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

问题是:我看到的值太大了。我3684414156现在开始。这里可能出什么问题?

编辑:从EBX更改为EDI,但结果仍然相似。一定是rdtsc本身。在调试器中,我可以看到第二个测量结果分别为0x7f61e078和第一个0x42999940,在减去后仍可得出1019758392

编辑:这是我的makefile。也许我编译不正确:

compile: measurement.s measurement.c
    gcc -g measurement.s measurement.c -o ./build/measurement -m32
Run Code Online (Sandbox Code Playgroud)

编辑:这是我看到的确切结果:

Instruction took 4294966680 cycles 
Instruction took 4294966696 cycles 
Instruction took 4294966688 cycles 
Instruction took 4294966672 cycles 
Instruction took 4294966680 cycles 
Instruction took 4294966688 cycles 
Instruction took 4294966688 cycles 
Instruction took 4294966696 cycles 
Instruction took 4294966688 cycles 
Instruction took 4294966680 cycles 
Run Code Online (Sandbox Code Playgroud)

R..*_*R.. 5

cpuidClobbers ebx和许多其他寄存器。您需要避免在cpuid此处使用或将值保存在不会破坏的位置。