由于某些原因,我需要根据时间收益计数器(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);
}
答案 0 :(得分:2)
时间戳计数器始终为64位,请参阅此语句on the Wipedia page:
时间戳计数器(TSC)是Pentium以来所有x86处理器上的64位寄存器。
出于某种原因,您只获得了32位的截断值,这就是它包装的原因。 64位值需要146年的连续计数才能在4 GHz下进行包装。
您的代码似乎希望同时使用eax
和edx
来保存两个32位,正如预期的那样。将值移动到单个C变量时必须出错。我相信您使用的代码段是GCC;或许那不再是你的编译器了吗?
检查生成的程序集,并检查编译器文档以获取正确的内部函数。 This question有一些很好的答案,特定于编译器的程序集。