【问题标题】:How does this code calculate the number of CPU cycles elapsed?此代码如何计算经过的 CPU 周期数?
【发布时间】:2011-04-23 07:45:54
【问题描述】:

取自this SO thread,这段代码计算在//1//2 行之间运行代码所经过的CPU 周期数。

$ cat cyc.c 
#include<stdio.h>

static __inline__ unsigned long long rdtsc(void)
{
  unsigned long long int x;
     __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
     return x;
}

int main() {
    unsigned long long cycles = rdtsc(); //1
    cycles = rdtsc() - cycles;           //2
    printf("Time is %d\n", (unsigned)cycles);
    return 0;
}

$ gcc cyc.c -o cyc
$ ./cyc
Time is 73
$ ./cyc
Time is 74
$ ./cyc
Time is 63
$ ./cyc
Time is 73
$

rdtsc() 函数是如何工作的?

【问题讨论】:

    标签: c cpu cpu-cycles


    【解决方案1】:

    该函数执行 x86 指令 RTDSC,其操作码为0x0f, 0x31。处理器在内部跟踪时钟周期,并读取该数字。

    当然,这只适用于 x86 procs,其他处理器需要不同的指令。

    时间戳计数器是一个 64 位寄存器,自 Pentium 以来出现在所有 x86 处理器上。它计算自重置以来的刻度数。指令 RDTSC 在 EDX:EAX 中返回 TSC。它的操作码是 0F 31.[1]奔腾的竞争对手,如 Cyrix 6x86 并不总是有 TSC,可能会认为 RDTSC 是非法指令。 Cyrix 在他们的 MII 中包含一个时间戳计数器。

    http://en.wikipedia.org/wiki/Time_Stamp_Counter

    【讨论】:

    • "=A" 部分有什么作用?
    • 在一些molticore AMD处理器上也有问题,因为它们每个都有自己的不同步的计数器,所以如果你在取时间戳时碰巧在不同的核心上运行,你可能会有惊喜.所以,让操作系统让这个线程在同一个内核上运行是个好主意。
    • @Lazer,这是一个小小的 GCC 魔法,它表示 EDX:EAX 中的值应该放入 C 变量 x - gcc.gnu.org/onlinedocs/gcc/…。查看 Intel 部分下的“A”条目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-12-27
    • 2014-02-03
    • 2018-02-11
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多