GetLocalTime()API时间解析
我需要找出应用程序中某个函数所花费的时间。应用程序是MS VIsual Studio 2005解决方案,所有C代码。
我使用Windows API GetLocalTime(SYSTEMTIME *)来获取要测量时间的函数调用前后的当前系统时间。
但这有一个缺点,就是最低分辨率只有1毫秒。没有什么比这更重要的了。因此,我无法在微秒内获得任何时间粒度。
我知道time()给出自纪元时间起经过的时间,它的分辨率也为1毫秒(无微秒)
1.)是否还有其他Windows API可以提供以微秒为单位的时间,我可以用它来衡量函数消耗的时间?
-广告
解决方案
回答
我们可以尝试使用clock()来提供两点之间的"滴答声"数量。 "滴答"是处理器可以测量的最小时间单位。
附带说明一下,我们不能使用clock()来确定实际时间,而只能确定程序中两点之间的滴答数。
回答
在Windows上,我们可以使用"高性能计数器API"。签出:QueryPerformanceCounter和QueryPerformanceCounterFrequency了解详细信息。
回答
还有其他可能性。
QueryPerformanceCounter和QueryPerformanceFrequency
QueryPerformanceCounter将返回一个"性能计数器",它实际上是CPU管理的64位计数器,从计算机开机开始,该计数器将从0开始递增。该计数器的频率由QueryPerformanceFrequency返回。要获得以秒为单位的时间基准,请将性能计数器除以性能频率。在德尔福:
function QueryPerfCounterAsUS: int64; begin if QueryPerformanceCounter(Result) and QueryPerformanceFrequency(perfFreq) then Result := Round(Result / perfFreq * 1000000); else Result := 0; end;
在多处理器平台上,无论线程当前在哪个CPU上运行,QueryPerformanceCounter都应返回一致的结果。但是,偶尔会出现一些问题,通常是由硬件芯片或者BIOS中的错误引起的。通常,补丁是由主板制造商提供的。来自MSDN的两个示例:
- 使用QueryPerformanceCounter函数的程序在Windows Server 2003和Windows XP中可能无法正常运行
- 性能计数器值可能会意外地飞跃
QueryPerformanceCounter的另一个问题是运行速度很慢。
RDTSC指令
如果可以将代码限制为一个CPU(SetThreadAffinity),则可以使用RDTSC汇编程序指令直接从处理器查询性能计数器。
function CPUGetTick: int64; asm dw 310Fh // rdtsc end;
RDTSC结果以与QueryPerformanceCounter相同的频率递增。用QueryPerformanceFrequency除以时间(以秒为单位)。
QueryPerformanceCounter比RDTSC要慢得多,因为它必须考虑多个CPU和频率可变的CPU。从雷蒙·陈(Raymon Chen)的博客中:
(QueryPerformanceCounter) counts elapsed time. It has to, since its value is governed by the QueryPerformanceFrequency function, which returns a number specifying the number of units per second, and the frequency is spec'd as not changing while the system is running. For CPUs that can run at variable speed, this means that the HAL cannot use an instruction like RDTSC, since that does not correlate with elapsed time.
timeGetTime
TimeGetTime属于Win32多媒体Win32函数。至少在现代硬件上,它以1 ms的分辨率返回以毫秒为单位的时间。如果在完成后开始测量time和timeEndPeriod(1)之前运行timeBeginPeriod(1),这并没有什么坏处。
GetLocalTime和GetSystemTime
在Vista之前,GetLocalTime和GetSystemTime都以毫秒精度返回当前时间,但它们的精确度不能达到毫秒。它们的精度通常在10到55毫秒的范围内。 (精度与精度不同)
在Vista上,GetLocalTime和GetSystemTime均以1 ms的分辨率工作。
回答
多处理器系统的一种警告:
来自http://msdn.microsoft.com/zh-cn/library/ms644904(VS.85).aspx
在多处理器计算机上,调用哪个处理器无关紧要。但是,由于基本输入/输出系统(BIOS)或者硬件抽象层(HAL)中的错误,我们在不同的处理器上可以获得不同的结果。若要指定线程的处理器相似性,请使用SetThreadAffinityMask函数。
阿尔·韦纳