No announcement yet.

On GetTickCount

  • Filter
  • Time
  • Show
Clear All
new posts

  • On GetTickCount

    I noticed in How fast can we compute the dot product? that GetTickCount was being used for timing code.

    From SDK docs
    The GetTickCount function retrieves the number of milliseconds that have elapsed since the system was started. It is limited to the resolution of the system timer.
    The system timer on my machine ticks at 64Hz ie 15.625ms per tick.

    On running
    #Compile  Exe
    #Register None
    #Dim      All
    #TOOLS    OFF
    %NOMMIDS = 1
    %NOGDI = 1
    #Include "WIN32API.INC"
    Global qFreq, qOverhead, qStart, qStop As Quad
    Global f As String
    Macro InitializeTimer
      f = "#####.######"
      QueryPerformanceFrequency qFreq
      QueryPerformanceCounter qStart ' Intel suggestion. First use may be suspect
      QueryPerformanceCounter qStart ' So, wack it twice <smile>
      QueryPerformanceCounter qStop
      qOverhead = qStop - qStart     ' Relatively small
    End Macro
    Macro StartTimer = QueryPerformanceCounter qStart
    Macro StopTimer = QueryPerformanceCounter qStop
    Macro sTimeTaken = Using$(f,(qStop - qStart - qOverhead)*1000/qFreq) + "ms"
    Macro nTimeTaken = (qStop - qStart - qOverhead)*1000/qFreq
    Function PBMain() As Long
    Local first, second, NumberOfms, i As Long, test As Quad
      NumberOfms = 1006
      test = qFreq * NumberOfms
      For i = 1 To 5
        first = GetTickCount ' On my machine the first call to GetTickCount is unreliable
        first = GetTickCount
          If (qStop - qStart - qOverhead) * 1000 >= test Then Exit Loop
          second = GetTickCount
        Print second - first;" ";sTimeTaken
      Print : Print "Done"
    End Function
    I get
     1000   1006.000060ms
     1000   1006.000090ms
     1015   1006.000075ms
     1000   1006.000041ms
     1016   1006.000116ms
    I chose 1006ms deliberately to emphasize the influence of the system timer.

    With code sections in the 100ms range and less the results are very poor.

    For accurate timings I would suggest the above timer macros or TIX if you prefer [CC5 and/or PB9].

  • #2
    Hi David,

    thanks for the info, you are right. Some of the info you posted I didn't know.

    I also prefer QueryPerformanceFrequency, but I was ... lazy ... to use it, so I picked GetTickCount as I remember his declaration( and I thought how nice it is instead of using TIMER). Won't do it again

    [email protected]


    • #3
      > but I was ... lazy

      So am I - that is why I wrote the timer macros - I figured that if I was too lazy to type StartTimer and so on then I may as well give up; and, of course it is just as easy as typing GetTickCount.

      It is worth mentioning that for timing long intervals not for code section timing GetTickCount is more robust than the Performance Counter. Microsoft recommend the Performance Counter rather than RDTSC becuase of possible misbehaviour but I have read that the Performance Counter is not immune to the same issues. Statistically, the shorter the interval the less likely that we will see such goings on - so the Performance Counter is ideal for timing code sections.

      We tend not to but to be thorough we should repeat timing calculations. To convince myself that Code A is faster than Code B I'll do 24 calculations, sort them then reject the two slowest and the two fastest before any averaging is done. If they look close then I'll see how the confidence limits pan out. If they overlap then Code A is not rejected. Some may say that is a bit 'over the top' but I reckon that if we have good reason to examine alternative approaches on speed grounds we may as well do the job right.


      • #4
        Thanks again for more info,

        I never used QueryPerformanceCounter for longer time intervals, I use it to measure time blocks ranging from 0.0002 to 1 second ( frame rate measurement ). In this time span, the difference of precision between GetTickCount and QPC is very noticeable.

        [email protected]