题
在Win32中,有没有办法获得一个独特的cpu循环计数或类似的东西,对于多个进程/语言/系统/等是统一的。
我正在创建一些日志文件,但是必须生成多个日志文件,因为我们正在托管.NET运行时,并且我想避免从一个调用到另一个来进行日志记录。因此,我认为我只生成两个文件,将它们组合起来,然后对它们进行排序,以获得涉及跨世界调用的连贯时间线。
但是,每次通话都不会增加GetTickCount,因此不可靠。是否有更好的数字,以便在排序时以正确的顺序接听电话?
修改:感谢 @Greg 让我顺利进入QueryPerformanceCounter这就是诀窍。
解决方案
您可以使用 RDTSC CPU指令(假设为x86)。该指令给出CPU周期计数器,但要注意它会非常快地增加到其最大值,然后重置为0.正如维基百科文章所提到的,你可能最好使用 QueryPerformanceCounter 功能。
其他提示
这是一篇有趣的文章!说不要使用RDTSC,而是而是使用 QueryPerformanceCounter 。
结论:
使用常规的旧
timeGetTime()
来做 对许多人而言,时机并不可靠 基于Windows的操作系统 因为系统的粒度 计时器可高达10-15 毫秒,意思是timeBeginPeriod(1)
只准确到 10-15毫秒。 [注意 基于NT的高粒度发生 像Windows NT这样的操作系统 2000年和XP。 Windows 95和98倾向于 有更好的粒度, 大约1-5毫秒。]但是,如果你打电话
timeEndPeriod(1)
在开头 你的程序(和Sleep()
at 结束),Sleep(1)
通常会 精确到1-2毫秒, 并将为您提供极致 准确的时间信息。
Sleep(2)
行为相似;长度QueryPerformanceFrequency
实际上睡觉的时间 与...携手并进 粒度QueryPerformanceCounter
,所以之后 打电话给<=>一次, <=>实际上会睡1-2 毫秒,<=> 2-3,等等 开(而不是以增量睡觉 高达10-15毫秒)。用于更高精度的定时 (毫秒精度),你会的 可能想避免使用 汇编助记符RDTSC,因为它 难以校准;相反,使用 <=>和 <=>,这是 精确到小于10微秒 (0.00001秒)。
对于简单的计时,都是timeGetTime 和QueryPerformanceCounter运行良好, 和QueryPerformanceCounter是 显然更准确。但是,如果 你需要做任何<!>时间 停顿QUOT <!>; (例如那些必要的 帧率限制),你需要 小心坐在一个循环呼唤 QueryPerformanceCounter,等待 它达到一定的价值;这将 吃掉100%的处理器。 相反,考虑一个混合方案, 你叫Sleep(1)的地方(别忘了 timeBeginPeriod(1)首先!)每当 你需要传递超过1毫秒的时间 时间,然后才进入 QueryPerformanceCounter 100%-busy循环 完成最后一次<!> lt; 1/1000 你需要的第二个延迟。这个 会给你超准确的延迟 (精确到10微秒),用 非常小的CPU使用率。看代码 上方。
System.Diagnostics.Stopwatch.GetTimestamp()返回自时间原点以来的CPU周期数(可能在计算机启动时,但我不确定)并且我从未看到它在2次调用之间没有增加。 / p>
CPU Cycles将特定于每台计算机,因此您无法使用它来合并两台计算机之间的日志文件。
RDTSC输出可能取决于当前内核的时钟频率,对于现代CPU而言,它既不是常数,也不是在多核机器中是一致的。
使用系统时间,如果处理来自多个系统的供稿,则使用NTP时间源。您可以通过这种方式获得可靠,一致的时间读数;如果开销太大而无法满足您的需求,请使用 HPET 计算自此之后的时间。最后已知的可靠时间读数比单独使用HPET要好。
使用GetTickCount并在合并日志文件时添加另一个计数器。不会在不同的日志文件之间给出完美的序列,但它至少会以正确的顺序保存每个文件的所有日志。