gettimeofday() 能保证达到微秒的分辨率吗?
- 2024-10-18 09:00:00
- admin 原创
- 69
问题描述:
我正在将一个最初为 Win32 API 编写的游戏移植到 Linux(好吧,将 Win32 端口的 OS X 端口移植到 Linux)。
我已经QueryPerformanceCounter
通过提供自进程启动以来的 uSeconds 来实现:
BOOL QueryPerformanceCounter(LARGE_INTEGER* performanceCount)
{
gettimeofday(&currentTimeVal, NULL);
performanceCount->QuadPart = (currentTimeVal.tv_sec - startTimeVal.tv_sec);
performanceCount->QuadPart *= (1000 * 1000);
performanceCount->QuadPart += (currentTimeVal.tv_usec - startTimeVal.tv_usec);
return true;
}
这与QueryPerformanceFrequency()
给出一个常数 1000000 作为频率相结合,在我的计算机上uSeconds
运行良好,并给了我一个包含自程序启动以来内容的 64 位变量。
那么这可以移植吗?我不想发现如果内核以某种方式编译或类似方式编译,它会有所不同。不过,我可以接受它不能移植到 Linux 以外的其他系统。
解决方案 1:
也许吧。但您有更大的问题。gettimeofday()
如果系统上有更改计时器的进程(即 ntpd),则会导致计时不正确。不过,在“普通”Linux 上,我相信的分辨率gettimeofday()
是 10us。因此,它可以根据系统上运行的进程向前和向后跳转时间。这实际上使您的问题的答案为否。
您应该查看clock_gettime(CLOCK_MONOTONIC)
时间间隔。由于多核系统和外部时钟设置等原因,它遇到的问题较少。
另外,查看clock_getres()函数。
解决方案 2:
适用于英特尔处理器的高分辨率、低开销计时
如果您使用的是 Intel 硬件,以下是读取 CPU 实时指令计数器的方法。它将告诉您自处理器启动以来执行的 CPU 周期数。这可能是您可以获得的性能测量最精细的计数器。
请注意,这是 CPU 周期数。在 Linux 上,您可以从 /proc/cpuinfo 获取 CPU 速度,然后除以得到秒数。将其转换为双精度数非常方便。
当我在我的盒子上运行这个时,我得到了
11867927879484732
11867927879692217
it took this long to call printf: 207485
这是英特尔开发人员指南,其中提供了大量的详细信息。
#include <stdio.h>
#include <stdint.h>
inline uint64_t rdtsc() {
uint32_t lo, hi;
__asm__ __volatile__ (
"xorl %%eax, %%eax
"
"cpuid
"
"rdtsc
"
: "=a" (lo), "=d" (hi)
:
: "%ebx", "%ecx");
return (uint64_t)hi << 32 | lo;
}
main()
{
unsigned long long x;
unsigned long long y;
x = rdtsc();
printf("%lld
",x);
y = rdtsc();
printf("%lld
",y);
printf("it took this long to call printf: %lld
",y-x);
}
解决方案 3:
@Bernard:
我必须承认,您的大部分示例我都看不懂。不过,它确实可以编译,而且似乎可以工作。这对于 SMP 系统或 SpeedStep 来说安全吗?
这是个好问题……我认为代码没问题。从实际角度来看,我们每天都在公司使用它,并且我们在各种各样的机器上运行,从 2 核到 8 核都有。当然,YMMV 等,但它似乎是一种可靠且低开销(因为它不会将上下文切换到系统空间)的计时方法。
通常它的工作原理是:
将代码块声明为汇编程序(并且是易失性的,因此优化器将不改变它)。
执行 CPUID 指令。除了获取一些 CPU 信息(我们不做任何处理)之外,它还会同步 CPU 的执行缓冲区,这样时序就不会受到无序执行的影响。
执行 rdtsc(读取时间戳)执行。这将获取自处理器重置以来执行的机器周期数。这是一个 64 位值,因此在当前 CPU 速度下,它将每 194 年左右绕回一次。有趣的是,在原始 Pentium 参考中,他们指出它每 5800 年左右绕回一次。
最后几行将寄存器中的值存储到变量 hi 和 lo 中,并将其放入 64 位返回值中。
具体说明:
无序执行会导致不正确的结果,因此我们执行“cpuid”指令,它除了向您提供有关 CPU 的一些信息外,还会同步任何无序指令的执行。
大多数操作系统在启动时都会同步 CPU 上的计数器,因此答案在几纳秒内即可确定。
休眠的评论可能是正确的,但实际上您可能并不关心跨越休眠边界的时间。
关于 speedstep:较新的 Intel CPU 可以补偿速度变化并返回调整后的计数。我快速扫描了我们网络上的一些盒子,发现只有一个盒子没有它:运行一些旧数据库服务器的 Pentium 3。(这些是 Linux 盒子,所以我用 grep constant_tsc /proc/cpuinfo 检查)
我不太清楚 AMD CPU 的情况,我们主要经营英特尔产品,尽管我知道我们的一些低级系统专家做过 AMD 评估。
希望这能满足你的好奇心,这是一个有趣且(在我看来)研究不足的编程领域。你知道 Jeff 和 Joel 当时在谈论程序员是否应该了解 C 语言吗?我冲他们喊道:“嘿,忘掉那些高级 C 语言的东西吧……如果你想知道计算机在做什么,你应该学习汇编语言!”
解决方案 4:
您可能对Linux FAQ感兴趣clock_gettime(CLOCK_REALTIME)
解决方案 5:
Wine 实际上是使用 gettimeofday() 来实现 QueryPerformanceCounter(),并且众所周知它可以使许多 Windows 游戏在 Linux 和 Mac 上运行。
开始http://source.winehq.org/source/dlls/kernel32/cpu.c#L312
指向http://source.winehq.org/source/dlls/ntdll/time.c#L448
解决方案 6:
gettimeofday() 的实际精度取决于硬件架构。Intel 处理器以及 SPARC 计算机提供测量微秒的高精度计时器。其他硬件架构则使用系统计时器,该计时器通常设置为 100 Hz。在这种情况下,时间精度会不太准确。
我从高分辨率时间测量和计时器第一部分获得了这个答案
解决方案 7:
因此它明确指出了微秒,但表示系统时钟的分辨率未指定。我猜想这里的分辨率是指它将增加的最小量是多少?
数据结构定义为以微秒作为测量单位,但这并不意味着时钟或操作系统实际上能够进行精细的测量。
正如其他人所建议的那样,gettimeofday()
这很糟糕,因为设置时间可能会导致时钟偏差并影响您的计算。 clock_gettime(CLOCK_MONOTONIC)
这就是您想要的,并且clock_getres()
会告诉您时钟的精度。
解决方案 8:
这个答案提到了时钟调整的问题。保证滴答单位的问题和调整时间的问题都在 C++11 中通过<chrono>
库得到了解决。
该时钟std::chrono::steady_clock
保证不会被调整,而且它将相对于实际时间以恒定的速率前进,因此 SpeedStep 等技术一定不会对其产生影响。
您可以通过转换为其中一种std::chrono::duration
专业化(例如)来获取类型安全的单位std::chrono::microseconds
。使用此类型,刻度值使用的单位不会产生歧义。但是,请记住,时钟不一定具有此分辨率。您可以将持续时间转换为阿秒,而无需实际拥有如此精确的时钟。
解决方案 9:
根据我的经验以及我在网上读到的内容,答案是“否”,这并不能保证。这取决于 CPU 速度、操作系统、Linux 风格等。
解决方案 10:
在 SMP 系统中读取 RDTSC 并不可靠,因为每个 CPU 都维护自己的计数器,并且不能保证每个计数器相对于另一个 CPU 同步。
我可能会建议尝试clock_gettime(CLOCK_REALTIME)
。posix 手册指出这应该在所有兼容系统上实现。它可以提供纳秒计数,但您可能需要检查clock_getres(CLOCK_REALTIME)
系统以查看实际分辨率是多少。
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件