GetLocalTime() API time resolution

前端 未结 4 832
臣服心动
臣服心动 2021-01-12 10:06

I need to find out time taken by a function in my application. Application is a MS VIsual Studio 2005 solution, all C code.

I used thw windows API GetLocalTime(SYST

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-12 10:33

    There are some other possibilities.

    QueryPerformanceCounter and QueryPerformanceFrequency

    QueryPerformanceCounter will return a "performance counter" which is actually a CPU-managed 64-bit counter that increments from 0 starting with the computer power-on. The frequency of this counter is returned by the QueryPerformanceFrequency. To get the time reference in seconds, divide performance counter by performance frequency. In Delphi:

    function QueryPerfCounterAsUS: int64;     
    begin
      if QueryPerformanceCounter(Result) and
         QueryPerformanceFrequency(perfFreq)
      then
        Result := Round(Result / perfFreq * 1000000);
      else
        Result := 0;
    end;
    

    On multiprocessor platforms, QueryPerformanceCounter should return consistent results regardless of the CPU the thread is currently running on. There are occasional problems, though, usually caused by bugs in hardware chips or BIOSes. Usually, patches are provided by motherboard manufacturers. Two examples from the MSDN:

    • Programs that use the QueryPerformanceCounter function may perform poorly in Windows Server 2003 and in Windows XP
    • Performance counter value may unexpectedly leap forward

    Another problem with QueryPerformanceCounter is that it is quite slow.

    RDTSC instruction

    If you can limit your code to one CPU (SetThreadAffinity), you can use RDTSC assembler instruction to query performance counter directly from the processor.

    function CPUGetTick: int64;
    asm
      dw 310Fh // rdtsc
    end;
    

    RDTSC result is incremented with same frequency as QueryPerformanceCounter. Divide it by QueryPerformanceFrequency to get time in seconds.

    QueryPerformanceCounter is much slower thatn RDTSC because it must take into account multiple CPUs and CPUs with variable frequency. From Raymon Chen's blog:

    (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 belongs to the Win32 multimedia Win32 functions. It returns time in milliseconds with 1 ms resolution, at least on a modern hardware. It doesn't hurt if you run timeBeginPeriod(1) before you start measuring time and timeEndPeriod(1) when you're done.

    GetLocalTime and GetSystemTime

    Before Vista, both GetLocalTime and GetSystemTime return current time with millisecond precision, but they are not accurate to a millisecond. Their accuracy is typically in the range of 10 to 55 milliseconds. (Precision is not the same as accuracy) On Vista, GetLocalTime and GetSystemTime both work with 1 ms resolution.

提交回复
热议问题