Winapi 如何在Win32中获取CPU周期计数?

Winapi 如何在Win32中获取CPU周期计数?,winapi,timer,cpu-cycles,Winapi,Timer,Cpu Cycles,在Win32中,是否有任何方法可以获得唯一的cpu周期计数或类似的数据,这些数据对于多个进程/语言/系统/等是统一的 我正在创建一些日志文件,但必须生成多个日志文件,因为我们正在托管.NET运行时,我希望避免从一个调用另一个来记录日志。因此,我想我只需要生成两个文件,组合它们,然后对它们进行排序,就可以得到一个涉及跨世界通话的连贯的时间表 然而,GetTickCount并不是每次调用都增加,所以这是不可靠的。是否有更好的号码,以便我在排序时按正确的顺序接听电话 编辑:多亏了这一点,我开始使用Q

在Win32中,是否有任何方法可以获得唯一的cpu周期计数或类似的数据,这些数据对于多个进程/语言/系统/等是统一的

我正在创建一些日志文件,但必须生成多个日志文件,因为我们正在托管.NET运行时,我希望避免从一个调用另一个来记录日志。因此,我想我只需要生成两个文件,组合它们,然后对它们进行排序,就可以得到一个涉及跨世界通话的连贯的时间表

然而,GetTickCount并不是每次调用都增加,所以这是不可靠的。是否有更好的号码,以便我在排序时按正确的顺序接听电话


编辑:多亏了这一点,我开始使用QueryPerformanceCounter,它成功了。

您可以使用CPU指令(假设为x86)。此指令给出CPU周期计数器,但请注意,它将很快增加到最大值,然后重置为0。正如维基百科文章所提到的,您最好使用这个函数。

说不要使用RDTSC,而是使用RDTSC

结论:

使用常规的旧
timeGetTime()
执行 在许多情况下,时间不可靠 基于Windows的操作系统 因为系统的粒度 定时器可高达10-15秒 毫秒,意思是
timeGetTime()
仅对 10-15毫秒。[请注意 基于NT的系统会出现高粒度 Windows NT等操作系统, 2000和XP。Windows 95和98 为了获得更好的粒度, 大约1-5毫秒。]

然而,如果你打电话
timeBeginPeriod(1)
您的程序(和
timeEndPeriod(1)
结束时,
timeGetTime()
通常 精确到1-2毫秒, 并将为您提供非常好的服务 准确的时间信息

Sleep()
的行为类似;长度
Sleep()
实际睡眠的时间 因为它与
timeGetTime()
的粒度,因此 调用
timeBeginPeriod(1)
一次,
睡眠(1)
将实际睡眠1-2天 毫秒,
Sleep(2)
2-3秒,依此类推 打开(而不是以增量睡眠) 高达10-15毫秒)

用于更高精度的定时 (亚毫秒精度),您将 可能想避免使用 程序集助记符RDTSC,因为它是 难以校准;相反,使用
QueryPerformanceFrequency
查询性能计数器
,它们是 精确到10微秒以下 (0.00001秒)

对于简单的计时,timeGetTime和 查询性能计数器工作正常, 并且QueryPerformanceCounter是 显然更准确。然而,如果 你需要做任何形式的“定时”测试 暂停”(例如,为 帧速率限制),您需要 小心坐在一个循环中呼叫 QueryPerformanceCounter,正在等待 它需要达到一定的价值;这将 吃掉100%的处理器。 相反,考虑混合方案, 你称之为睡眠的地方(1)(别忘了 timeBeginPeriod(1)优先!)无论何时 您需要通过超过1毫秒的 时间,然后只输入 QueryPerformanceCounter 100%忙循环 完成最后一次<1/1000次 你需要的第二次延迟。这 将为您提供超精确的延迟 (精确到10微秒),带有 非常低的CPU使用率。参见代码 上面


合并日志文件时,使用GetTickCount并添加另一个计数器。不会为您提供不同日志文件之间的完美顺序,但它至少会将每个文件中的所有日志保持在正确的顺序。


CPU周期将针对每台计算机而定,因此您不能使用它在两台计算机之间合并日志文件。

RDTSC输出可能取决于当前内核的时钟频率,对于现代CPU来说,时钟频率既不是恒定的,也不是一致的,在多核机器中


使用系统时间,如果处理来自多个系统的提要,则使用NTP时间源。通过这种方式,您可以获得可靠、一致的时间读数;如果开销对您来说太大,那么使用来计算自上次已知的可靠时间读取以来经过的时间比单独使用HPET要好。

谢谢,我只想在同一时间段内合并在同一台计算机上生成的文件,这样就行了。现在,我只需要找出该方法实际调用的内容:)滴答计数似乎在毫秒输出的同时增加,这就是为什么我需要更精确的东西。请避免使用timeBeginPeriod();它会影响系统范围的计划程序,并可能导致节能问题。