c - rdtsc,循环太多

标签 c assembly x86 rdtsc

#include <stdio.h>
static inline unsigned long long tick() 
{
        unsigned long long d;
        __asm__ __volatile__ ("rdtsc" : "=A" (d) );
        return d;
}

int main()
{
        long long res;
        res=tick();

        res=tick()-res;
        printf("%d",res);
        return 0;
}

我已经使用 gcc 编译了这段代码,并进行了 -O0 -O1 -O2 -O3 优化。而且我总是得到 2000-2500 个周期。谁能解释这个输出的原因?如何度过这些周期?

第一个函数“tick”是错误的。这是对的

另一个版本的函数“tick”

static __inline__ unsigned long long tick()
{
  unsigned hi, lo;
  __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
  return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}

这是-O3的汇编代码

 .file  "rdtsc.c"
.section    .rodata.str1.1,"aMS",@progbits,1
.LC0:
    .string "%d"
    .text
    .p2align 4,,15
.globl main
    .type   main, @function
main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl   -4(%ecx)
    pushl   %ebp
    movl    %esp, %ebp
    subl    $40, %esp
    movl    %ecx, -16(%ebp)
    movl    %ebx, -12(%ebp)
    movl    %esi, -8(%ebp)
    movl    %edi, -4(%ebp)
#APP
# 6 "rdtsc.c" 1
    rdtsc
# 0 "" 2
#NO_APP
    movl    %edx, %edi
    movl    %eax, %esi
#APP
# 6 "rdtsc.c" 1
    rdtsc
# 0 "" 2
#NO_APP
    movl    %eax, %ecx
    movl    %edx, %ebx
    subl    %esi, %ecx
    sbbl    %edi, %ebx
    movl    %ecx, 4(%esp)
    movl    %ebx, 8(%esp)
    movl    $.LC0, (%esp)
    call    printf
    movl    -16(%ebp), %ecx
    xorl    %eax, %eax
    movl    -12(%ebp), %ebx
    movl    -8(%ebp), %esi
    movl    -4(%ebp), %edi
    movl    %ebp, %esp
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .size   main, .-main
    .ident  "GCC: (Debian 4.3.2-1.1) 4.3.2"
    .section    .note.GNU-stack,"",@progbits

这是CPU

processor   : 0
vendor_id   : GenuineIntel
cpu family  : 15
model       : 4
model name  : Intel(R) Xeon(TM) CPU 3.00GHz
stepping    : 3
cpu MHz     : 3000.105
cache size  : 2048 KB
fdiv_bug    : no
hlt_bug     : no
f00f_bug    : no
coma_bug    : no
fpu     : yes
fpu_exception   : yes
cpuid level : 5
wp      : yes
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss constant_tsc up pebs bts pni
bogomips    : 6036.62
clflush size    : 64

最佳答案

我已经在不同 Intel CPU 上运行的多个 Linux 发行版上尝试了您的代码(不可否认,所有这些发行版都比您似乎使用的 Pentium 4 HT 630 更新)。在所有这些测试中,我得到的值介于 25 到 50 个周期之间。

我唯一与所有证据一致的假设是,您在虚拟机而不是裸机上运行操作系统,并且 TSC 正在虚拟化。

关于c - rdtsc,循环太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8322782/

相关文章:

c++ - 从 lua 5.2 调用 c 函数会产生语法错误

c - 如何正确初始化Raspberry?

x86 - x86 cpu有什么样的地址指令?

c++ - 线程和上下文切换 C++

C 推弹测试

c# - 从其他异常的 StackTrace 获取 BadImageFormatException

C 在 void 函数之后由指针发送的数组的值被修改

c - 为什么编译器生成的代码会一遍又一遍地在同一内存位置写入相同的内容?

c - 试图了解一个变量在这个小程序中从哪里获得它的值(value)

c++ - 将 GNU 汇编程序编译到 Windows