The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: cman on January 09, 2010, 07:48:14 PM

Title: GetTickCount()
Post by: cman on January 09, 2010, 07:48:14 PM
Is GetTickCount() fairly accurate for use in code timing? I want to compare some assembly code to some C code and need a method that will work in either type of source code. Thanks for any info.....
Title: Re: GetTickCount()
Post by: MichaelW on January 09, 2010, 08:04:52 PM
QuoteIs GetTickCount() fairly accurate for use in code timing?

If the duration of the test is long enough, yes. One problem with GetTickCount is the limited resolution, ~10ms. With the multimedia timer you can get the resolution down to ~1ms.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\winmm.inc
    includelib \masm32\lib\winmm.lib
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    print "GetTickCount resolution "
    xor edi, edi
    mov ebx, 500
    .WHILE ebx
      invoke GetTickCount
      mov esi, eax
      .REPEAT
        invoke GetTickCount
      .UNTIL eax != esi
      sub eax, esi
      add edi, eax
      dec ebx
    .ENDW
    mov eax, edi
    mov ecx, 500
    xor edx, edx
    div ecx
    print ustr$(eax),"ms",13,10

    print "timeGetTime resolution  "
    xor edi, edi
    mov ebx, 500
    .WHILE ebx
      invoke timeGetTime
      mov esi, eax
      .REPEAT
        invoke timeGetTime
      .UNTIL eax != esi
      sub eax, esi
      add edi, eax
      dec ebx
    .ENDW
    mov eax, edi
    mov ecx, 500
    xor edx, edx
    div ecx
    print ustr$(eax),"ms",13,10

    invoke timeBeginPeriod, 1
    print "timeBeginPeriod, 1",13,10

    print "GetTickCount resolution "
    xor edi, edi
    mov ebx, 500
    .WHILE ebx
      invoke GetTickCount
      mov esi, eax
      .REPEAT
        invoke GetTickCount
      .UNTIL eax != esi
      sub eax, esi
      add edi, eax
      dec ebx
    .ENDW
    mov eax, edi
    mov ecx, 500
    xor edx, edx
    div ecx
    print ustr$(eax),"ms",13,10

    print "timeGetTime resolution  "
    xor edi, edi
    mov ebx, 500
    .WHILE ebx
      invoke timeGetTime
      mov esi, eax
      .REPEAT
        invoke timeGetTime
      .UNTIL eax != esi
      sub eax, esi
      add edi, eax
      dec ebx
    .ENDW
    mov eax, edi
    mov ecx, 500
    xor edx, edx
    div ecx
    print ustr$(eax),"ms",13,10,13,10

    invoke timeEndPeriod, 1

    inkey "Press any key to exit..."
    exit
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start


And then there is the high-resolution performance counter, with a resolution in the microsecond range.

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


Title: Re: GetTickCount()
Post by: dedndave on January 09, 2010, 08:31:33 PM
you should be able to use Michael's timing.asm macros...

http://www.masm32.com/board/index.php?topic=770.msg5281#msg5281

you could make c-callable procs for counter_begin and counter_end
the stack values can be stored into global variables
just know that you'll have to measure the overhead time and subtract it out
Title: Re: GetTickCount()
Post by: hutch-- on January 10, 2010, 12:10:17 AM
The problem with any timing method run from ring3 is it regularly loses priority to system ring0 operations and this gives you a wandering in your results of about 3 to 5%. GetTickCount() is useful because it is simple to use but it is not well suited for very short durations. Over about a half second test the tolerance drops to under 1% and it is useful in that context but it means you must design a test that runs that long.

As is normally the case, design a test that is closest to the way you intend to use the code and you will get something like usful results. If you are testing the "attack" of an algo, how quickly it gets going and finishes, make a small test piece and run it many times, if you are testing the sustain rate of an algo design a much larger test with a large data sample and you will get a reasonably good idea of how fast it is.

Note that all timing systems have failings, those from ring3 suffer the wanders, those done in ring0 with drivers or boot disks are not running in a normal multitasking environment so the results are not that reliable in real world situations.

When you get a method that is giving you meaningful results, run it a number of times in sequance and average the results and you will come close to the best you can do.
Title: Re: GetTickCount()
Post by: MichaelW on January 10, 2010, 10:59:09 PM
I improved the cycle-count macros for Microsoft C that I posted here initially, and moved them to a more suitable location:

http://www.masm32.com/board/index.php?topic=13100.0
Title: Re: GetTickCount()
Post by: dedndave on January 11, 2010, 12:29:01 AM
you should consider posting that with the others Michael - so e1 can find it   :U
might give it a diff name, though   :bg  (count4C maybe ?)

http://www.masm32.com/board/index.php?topic=770.0