7

我需要找出我的应用程序中某个函数所花费的时间。应用程序是 MS VIsual Studio 2005 解决方案,所有 C 代码。

我使用 thw windows API GetLocalTime(SYSTEMTIME *) 来获取我想要测量时间的函数调用之前和之后的当前系统时间。但这有个缺点,它的最低分辨率只有1msec。在此之下什么都没有。所以我无法以微秒为单位获得任何时间粒度。

我知道给出自纪元时间以来经过的时间的 time() 的分辨率也为 1 毫秒(无微秒)

1.) 是否有任何其他 Windows API 以微秒为单位提供时间,我可以用它来测量我的函数消耗的时间?

-广告

4

4 回答 4

10

还有一些其他的可能性。

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;

在多处理器平台上,QueryPerformanceCounter应该返回一致的结果,而不管线程当前运行在哪个 CPU 上。但是,偶尔会出现问题,通常是由硬件芯片或 BIOS 中的错误引起的。通常,补丁由主板制造商提供。来自 MSDN 的两个示例:

QueryPerformanceCounter 的另一个问题是它非常慢。

RDTSC 指令

如果您可以将代码限制为一个 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) 并没有什么坏处。

GetLocalTime 和 GetSystemTime

在 Vista 之前,GetLocalTimeGetSystemTime都以毫秒精度返回当前时间,但它们不能精确到毫秒。它们的精度通常在 10 到 55 毫秒之间。(精度与精度不同)在 Vista 上,GetLocalTime 和 GetSystemTime 都以 1 毫秒的分辨率工作。

于 2008-09-08T14:06:28.807 回答
2

多处理器系统的一个注意事项:

来自http://msdn.microsoft.com/en-us/library/ms644904(VS.85).aspx

在多处理器计算机上,调用哪个处理器并不重要。但是,由于基本输入/输出系统 (BIOS) 或硬件抽象层 (HAL) 中的错误,您可能会在不同的处理器上获得不同的结果。要指定线程的处理器亲和性,请使用 SetThreadAffinityMask 函数。

艾尔维纳

于 2008-12-10T17:07:55.760 回答
2

您可以尝试使用clock()它将提供两点之间的“滴答声”数量。“滴答”是处理器可以测量的最小时间单位。

作为旁注,您不能使用 clock() 来确定实际时间 - 只有程序中两点之间的滴答数。

于 2008-09-08T13:12:25.567 回答
1

在 Windows 上,您可以使用“高性能计数器 API”。查看:QueryPerformanceCounterQueryPerformanceCounterFrequency了解详细信息。

于 2008-09-08T13:39:12.927 回答