gpt4 book ai didi

linux - 使用 RDTSC 获取 cpu 周期 - 为什么 RDTSC 的值总是增加?

转载 作者:IT王子 更新时间:2023-10-29 00:23:13 34 4
gpt4 key购买 nike

我想获取特定点的 CPU 周期。我当时使用这个功能:

static __inline__ unsigned long long rdtsc(void)
{
unsigned long long int x;
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
// broken for 64-bit builds; don't copy this code
return x;
}

(编者注:"=A" 对于 x86-64 是错误的;它选择 RDX 或 RAX。只有在 32 位模式下它才会选择 EDX :EAX 输出你想要的。见How to get the CPU cycle count in x86_64 from C++?。)

问题是它总是返回一个增加的数字(在每次运行中)。就好像它指的是绝对时间。

我是否错误地使用了函数?

最佳答案

只要您的线程保持在同一个 CPU 内核上,RDTSC 指令就会不断返回一个递增的数字,直到它回绕。对于 2GHz CPU,这会在 292 年后发生,因此这不是真正的问题。你可能不会看到它发生。如果您希望活那么久,请确保您的计算机重新启动,例如每 50 年重新启动一次。

RDTSC 的问题在于,您无法保证它在旧多核 CPU 的所有内核上同时启动,也无法保证它在旧多核 CPU 的所有 CPU 上同时启动-CPU板。
现代系统通常没有这样的问题,但这个问题也可以在旧系统上解决,方法是设置线程的亲缘关系,使其只在一个 CPU 上运行。这对应用程序性能不利,因此通常不应该这样做,但对于测量滴答,它就可以了。

(另一个“问题”是很多人使用 RDTSC 来测量时间,这不是它的作用,不是,但是你写了你想要 CPU 周期,所以这很好。如果你>确实使用 RDTSC 来测量时间,当省电或超升压或任何称为大量变频技术的启动时,您可能会感到惊讶。对于实际时间,clock_gettime 系统调用是在 Linux 下出奇的好。)

我会在 asm 语句中编写 rdtsc,这对我来说工作得很好,而且比一些晦涩的十六进制代码更具可读性。假设它是正确的十六进制代码(并且因为它既没有崩溃也没有返回一个不断增加的数字,看起来是这样),你的代码是好的。

如果你想测量一段代码所花费的滴答数,你想要一个滴答,你只需要减去不断增加的计数器的两个值。像 uint64_t t0 = rdtsc(); 这样的东西... uint64_t t1 = rdtsc() - t0;
请注意,如果需要与周围代码隔离的非常准确的测量,则需要序列化,即在调用 rdtsc 之前停止管道(或使用 rdtscp ,这只是在较新的处理器上受支持)。可以在每个特权级别使用的一个序列化指令是 cpuid

回复评论中的进一步问题:

当您打开计算机时,TSC 从零开始(并且 BIOS 将所有 CPU 上的所有计数器重置为相同的值,尽管几年前的某些 BIOS 并不能可靠地做到这一点)。

因此,从您的程序的角度来看,计数器从“过去的某个未知时间”开始,并且它总是随着 CPU 看到的每个时钟滴答而增加。因此,如果您现在和以后在不同的进程中执行返回该计数器的指令,它将返回一个更大的值(除非 CPU 在这期间被挂起或关闭)。同一程序的不同运行得到更大的数字,因为计数器不断增长。总是。

现在,clock_gettime(CLOCK_PROCESS_CPUTIME_ID) 是另一回事了。这是操作系统分配给进程的 CPU 时间。当您的流程开始时,它从零开始。一个新的过程也从零开始。因此,两个相互运行的进程将获得非常相似或相同的数字,而不会增长。

clock_gettime(CLOCK_MONOTONIC_RAW) 更接近 RDTSC 的工作方式(在一些较旧的系统上是用它实现的)。它返回一个不断增加的值。如今,这通常是 HPET。然而,这确实是时间,而不是滴答声。如果您的计算机进入低功耗状态(例如以正常频率的 1/2 运行),它将以相同的速度前进。

关于linux - 使用 RDTSC 获取 cpu 周期 - 为什么 RDTSC 的值总是增加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8602336/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com