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