我需要找出应用程序中某个函数所花费的时间。应用程序是 MS Visual Studio 2005 解决方案,全部是 C 代码。
我使用 Windows API GetLocalTime(SYSTEMTIME *) 来获取我想要测量时间的函数调用之前和之后的当前系统时间。
但其缺点是其最低分辨率仅为1毫秒。没有低于此的东西。所以我无法获得以微秒为单位的任何时间粒度。
我知道 time() 给出了自纪元时间以来经过的时间,分辨率也为 1 毫秒(没有微秒)
是否有任何其他 Windows API 可以提供以微秒为单位的时间,我可以用它来测量我的函数消耗的时间?
还有一些其他的可能性。
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;
在多处理器平台上,QueryPerformanceCounter 应该返回一致的结果,无论线程当前运行在哪个 CPU 上。不过,偶尔也会出现问题,通常是由硬件芯片或 BIOS 中的错误引起的。通常,补丁由主板制造商提供。来自 MSDN 的两个示例:
QueryPerformanceCounter 的另一个问题是它非常慢。
如果您可以将代码限制为一个 CPU (SetThreadAffinity),则可以使用 RDTSC 汇编指令直接从处理器查询性能计数器。
function CPUGetTick: int64;
asm
dw 310Fh // rdtsc
end;
RDTSC 结果以与 QueryPerformanceCounter 相同的频率递增。将其除以 QueryPerformanceFrequency 即可得到以秒为单位的时间。
QueryPerformanceCounter 比 RDTSC 慢得多,因为它必须考虑多个 CPU 和可变频率的 CPU。来自Raymon Chen的博客:
(QueryPerformanceCounter) 计算经过的时间。它必须如此,因为它的值是 由 QueryPerformanceFrequency 函数控制,该函数返回一个数字 指定每秒的单位数,并且频率指定为不 在系统运行时改变。
对于可以变速运行的CPU,这意味着HAL不能 使用 RDTSC 等指令,因为它与经过的时间无关。
TimeGetTime属于Win32多媒体Win32函数。它以毫秒为单位返回时间,分辨率为 1 毫秒,至少在现代硬件上是这样。如果您在开始测量时间之前运行 timeBeginPeriod(1) 并在完成后运行 timeEndPeriod(1) ,这不会有什么坏处。
在 Vista 之前,GetLocalTime 和 GetSystemTime 都以毫秒精度返回当前时间,但它们不精确到毫秒。它们的精度通常在 10 到 55 毫秒范围内。 (精度不等于准确度) 在 Vista 上,GetLocalTime 和 GetSystemTime 的分辨率均为 1 毫秒。
您可以尝试使用 clock() 它将提供两点之间的“刻度”数。 “滴答声”是处理器可以测量的最小时间单位。
顺便说一句,您不能使用 Clock() 来确定实际时间 - 只能确定程序中两点之间的滴答数。
关于多处理器系统的一个警告:
来自 http://msdn.microsoft.com/en-us/library/ms644904(VS.85).aspx
在多处理器计算机上,调用哪个处理器并不重要。但是,由于基本输入/输出系统 (BIOS) 或硬件抽象层 (HAL) 中的错误,您可能会在不同的处理器上获得不同的结果。要指定线程的处理器关联性,请使用 SetThreadAffinityMask 函数。
艾尔·韦纳
在 Windows 上,您可以使用“高性能计数器 API”。 查看:QueryPerformanceCounter 和 QueryPerformanceCounterFrequency 了解详细信息。