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



我正在尝试计算运行单个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

我正在 *.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;
}

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

编辑:从EBX变为EDI,但结果仍然相似。RDTSC本身必须有所作为。在调试器中,我可以看到第二个测量结果具有0x7F61E078和第一个0x42999940,在基础上,基曲面仍然可以给出1019758392

编辑:这是我的makefile。也许我正在错误地编译它:

compile: measurement.s measurement.c
    gcc -g measurement.s measurement.c -o ./build/measurement -m32

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

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 

cpuid clobbers ebx和许多其他寄存器。您需要在此处避免使用cpuid或将其保存在不会被堵塞的地方保存。

在您的更新版本中,不会阻止开始时间(bug @r。指出(:

sub %eax, %edi正在计算start - end。这是一个负数,即一个低于2^32的巨大无符号。如果您要使用%u,请在调试时习惯将其输出解释为位模式。

您想要end - start

和顺便说一句,使用lfence;它比cpuid要高得多。它可以保证在Intel上序列化指令执行(而不像完整的序列化指令那样冲洗商店缓冲区(。它在AMD CPU上也可以安全,并启用了幽灵缓解措施。

另请参见http://akaros.cs.berkeley.edu/lxr/akaros/kern/kern/kern/arch/x86/rdtsc_test.c,以获取一些不同的方法来序列化rdtsc和/或rdtscp。


另请参见获得CPU周期数?有关RDTSC的更多信息,尤其是它不计算核心时钟周期,而仅计算参考周期。因此闲置/涡轮会影响您的结果。

另外,一个指令的成本不是一维的。用RDTSC这样的单个指令(如(计时并不是特别有用。请参阅NASM中的RDTSCP始终返回相同的值,以了解有关如何测量单个指令的吞吐量/延迟/UOP的更多信息。

rdtsc可用于定时整个循环或更长的指令序列,比CPU的OOO执行窗口大。

最新更新