2008-09-26 18 views
7

在Win32中,有没有办法获得一个独特的CPU周期数或类似的东西,这对于多个进程/语言/系统等是一致的。如何在Win32中获取CPU周期数?

我正在创建一些日志文件,但必须生成多个日志文件,因为我们正在托管.NET运行时,并且我想避免从一个到另一个进行日志记录调用。因此,我认为我只是制作两个文件,合并它们,然后对它们进行排序,以获得涉及跨世界调用的连贯时间线。

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


编辑:由于@Greg是把我的轨道QueryPerformanceCounter的,该做的把戏。

回答

8

您可以使用RDTSC CPU指令(假设为x86)。该指令给出了CPU周期计数器,但请注意它会非常快速地增加到其最大值,然后重置为0.如维基百科文章中提到的那样,使用QueryPerformanceCounter函数可能会更好。

12

Heres an interesting article!说不使用RDTSC,而是使用QueryPerformanceCounter

结论:

使用普通的旧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)一次后, Sleep(1)实际上会睡1-2 毫秒,Sleep(2) 2-3,和因此 开启(而不是以高达10-15毫秒的增量 休眠)。

对于更高的精确定时 (亚毫秒级精度),你会 可能要避免使用 组装记忆RDTSC,因为它是 很难校准;相反,使用 QueryPerformanceFrequencyQueryPerformanceCounter,这是 精确到小于10微秒 (0.00001秒)。

对于简单的计时,都timeGetTime 和QueryPerformanceCounter的做工精良, 和QueryPerformanceCounter的是 显然更为准确。但是,如果 你需要做的任何一种“定时 暂停”(如必要 帧率限制)的,你需要 小心坐在一个循环中调用 QueryPerformanceCounter的,等待 它达到一定的值;这将使 吃掉100%的处理器。 相反,考虑混合方案, 在那里你调用sleep(1)(不要忘记 timeBeginPeriod(1)第一!),只要 你需要传递的 时间超过1毫秒,然后只进入 QueryPerformanceCounter的100% - 忙碌的回路 完成最后的< 1/1000的 秒延迟您需要。这 会给你超精确的延迟 (精确到10微秒),与 非常小的CPU使用率。请参阅上面的代码 。

+3

请避免timeBeginPeriod();它会影响整个系统的调度程序,并可能导致节能问题。 – MSalters 2008-09-26 13:03:04

1

使用GetTickCount并在合并日志文件时添加另一个计数器。不会给你在不同日志文件之间的完美序列,但它至少会保持每个文件的所有日志按正确的顺序排列。

+2

滴答计数似乎增加与毫秒输出重合,这就是为什么我需要更准确一些的原因。 – 2008-09-26 12:00:30

2

System.Diagnostics.Stopwatch.GetTimestamp()返回自时间原点以来的CPU周期数(可能在计算机启动时,但我不确定),我从来没有看到它在两次调用之间没有增加。

CPU周期将针对每台计算机特定,因此您无法使用它来合并2台计算机之间的日志文件。

+0

谢谢,我只会在同一时间段内合并在同一台计算机上生成的文件,这样才能工作。现在我只需要找出该方法实际调用的内容:) – 2008-09-26 11:59:37

2

RDTSC输出可能取决于当前内核的时钟频率,对于现代CPU而言,这种时钟频率既不恒定,也不依赖于多核机器。

使用系统时间,并且如果处理来自多个系统的订阅源使用NTP时间源。您可以通过这种方式获得可靠,一致的时间读数;如果开销太大以至于无法达到您的目的,则使用HPET计算自上次已知的可靠时间读数以来的时间比单独使用HPET的时间更长。