在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并在合并日志文件时添加另一个计数器。不会在不同的日志文件之间给出完美的序列,但它至少会以正确的顺序保存每个文件的所有日志。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top