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

2024-11-11 08:26:00
admin
原创
19
摘要:问题描述:我想获取特定点的 CPU 周期。我在该点使用此函数:static __inline__ unsigned long long rdtsc(void) { unsigned long long int x; __asm__ volatile (".byte 0x0f, 0x3...

问题描述:

我想获取特定点的 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 输出。请参阅如何从 C++ 获取 x86_64 中的 CPU 周期数?。)

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

我是否错误地使用了这些功能?


解决方案 1:

只要您的线程停留在同一个 CPU 核心上,RDTSC 指令就会不断返回一个不断增加的数字,直到它回绕。对于 2GHz CPU,这种情况会在 292 年后发生,因此这不是一个真正的问题。您可能不会看到它发生。如果您希望使用这么长时间,请确保您的计算机每 50 年重新启动一次。

RDTSC 的问题在于,您无法保证它在老款多核 CPU 的所有核心上都在同一时间点启动,也无法保证它在老款多 CPU 主板的所有 CPU 上都在同一时间点启动。

现代系统通常不会出现此类问题,但在老款系统上也可以通过设置线程的亲和性使其仅在一个 CPU 上运行来解决此问题。这对应用程序性能不利,因此通常不应这样做,但对于测量滴答声来说,这样做就没问题了。

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

我只想rdtscasm语句中写入,这对我来说很好用,而且比一些晦涩难懂的十六进制代码更易读。假设它是正确的十六进制代码(因为它既不会崩溃也不会返回不断增加的数字,所以看起来是这样),你的代码是好的。

如果您想要测量一段代码所用的滴答数,您想要滴答,您只需要减去不断增加的计数器的两个值。类似于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 运行),它仍将相同的速度前进。

解决方案 2:

关于 TSC 有很多令人困惑和/或错误的信息,所以我想尝试澄清其中的一些。

当英特尔首次引入 TSC(在原始奔腾 CPU 中)时,有明确的文档记录了它用于计算周期(而不是时间)。然而,当时 CPU 大多以固定频率运行,因此有些人忽略了文档记录的行为,而是用它来测量时间(最著名的是 Linux 内核开发人员)。他们的代码在后来的 CPU 中失效,这些 CPU 不以固定频率运行(由于电源管理等)。大约在那个时候,其他 CPU 制造商(AMD、Cyrix、Transmeta 等)感到困惑,一些制造商实施 TSC 来测量周期,一些制造商实施它来测量时间,一些制造商使其可配置(通过 MSR)。

随后,“多芯片”系统在服务器中变得越来越普遍;甚至后来还引入了多核。这导致不同核心上的 TSC 值之间出现细微差异(由于启动时间不同);但更重要的是,它还导致不同 CPU 上的 TSC 值出现巨大差异,这是由于 CPU 以不同的速度运行(由于电源管理和/或其他因素)。

从一开始就试图错误地使用它的人(用它来测量时间而不是周期的人)抱怨很多,并最终说服 CPU 制造商将 TSC 标准化为测量时间而不是周期。

当然,这是一团糟 - 例如,如果您支持所有 80x86 CPU,则需要大量代码才能确定 TSC 实际测量的内容;并且不同的电源管理技术(包括 SpeedStep 之类的东西,也包括睡眠状态之类的东西)可能会在不同的 CPU 上以不同的方式影响 TSC;因此 AMD 在 CPUID 中引入了一个“TSC 不变”标志,以告诉操作系统 TSC 可用于正确测量时间。

所有最新的 Intel 和 AMD CPU 都已经这样一段时间了 - TSC 计算时间,根本不测量周期。这意味着如果你想测量周期,你必须使用(特定型号的)性能监控计数器。不幸的是,性能监控计数器甚至更乱(由于其特定型号的性质和复杂的配置)。

解决方案 3:

已经有很好的答案了,Damon 已经在他的回答中提到了这一点,但我将从实际的 x86 手册(第 2 卷,4-301)中为 RDTSC 添加这一点:

将处理器的时间戳计数器(64 位 MSR)的当前值加载到 EDX:EAX 寄存器中。EDX 寄存器加载 MSR 的高 32 位,EAX 寄存器加载低 32 位。(在支持 Intel 64 架构的处理器上,RAX 和 RDX 的高 32 位均被清除。)

处理器在每个时钟周期内单调递增时间戳计数器 MSR,并在处理器重置时将其重置为 0。有关时间戳计数器行为的具体详细信息,请参阅《英特尔® 64 和 IA-32 架构软件开发人员手册》第 3B 卷第 17 章中的“时间戳计数器” 。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用