如何确定时间戳计数器(TSC)复位的次数

时间:2014-11-27 06:22:05

标签: c timestamp cpu

由于某些原因,我需要根据时间收益计数器(TSC)来衡量时间。要阅读TSC,我使用以下代码:

#include <stdio.h>
#include <inttypes.h>

inline volatile uint32_t RDTSC32() {
    register uint32_t TSC asm("eax");
    asm volatile (".byte 15, 49" : : : "eax", "edx");
    return TSC;
}

inline volatile uint64_t RDTSC64() {
    register uint64_t TSC asm("rax");
    asm volatile (".byte 15, 49" : : : "rax", "rdx");
    return TSC;
} 

int main() {
    while (1) {
        printf("%" PRIu64 "\n", RDTSC64());
    }
} 

当我对它进行测试时,它运行正常。除了一件事。当它达到最大计数器值(某些值大于4,256,448,731,在我的环境中)时,计数器值将重置为0并继续运行。

在这种情况下,有没有办法查看TSC重置了多少次?

例如,下面的代码不会打印正确的时差:

#include <stdio.h>

int main() {
    long long start, end;
    start = RDTSC64();
    // long long works to do
    end = RDTSC64();
    printf("%lld \n", end - start);
} 

1 个答案:

答案 0 :(得分:2)

时间戳计数器始终为64位,请参阅此语句on the Wipedia page

  

时间戳计数器(TSC)是Pentium以来所有x86处理器上的64位寄存器。

出于某种原因,您只获得了32位的截断值,这就是它包装的原因。 64位值需要1​​46年的连续计数才能在4 GHz下进行包装。

您的代码似乎希望同时使用eaxedx来保存两个32位,正如预期的那样。将值移动到单个C变量时必须出错。我相信您使用的代码段是GCC;或许那不再是你的编译器了吗?

检查生成的程序集,并检查编译器文档以获取正确的内部函数。 This question有一些很好的答案,特定于编译器的程序集。