News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

SetTimer vs Sleep

Started by oex, May 19, 2010, 04:37:27 PM

Previous topic - Next topic

oex

Thank you Michael and JJ both interesting posts.... I have run the test app with the following results:

Sleep(1) delay  = 1.990 ms
Sleep(10) delay = 10.946 ms
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

Siekmanski

You can try using the GetTime and the one-shot timer AdviseTime ( I'm using the one from DirectSound to fill the soundbuffer without the use of notifications  :bg)

Let the timer run in its own thread with high priority using CreateThread and SetThreadPriority
And create a timer-event with CreateEvent


GetTime delivers the time in the type REFERENCE_TIME

   coinvoke   g_pDS_Timer,IReferenceClock,GetTime,addr RefClockTime ; receives the current time, in 100-nanosecond units.

   coinvoke   g_pDS_Timer,IReferenceClock,AdviseTime,RefClockTime,StreamTime,DS_TimerEvent,addr pdwAdviseCookie


http://msdn.microsoft.com/ja-jp/library/cc369473(v=MSDN.10).aspx

oex

This is great guys.... So many ways to do nothing :lol
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

jj2007

One more, using timeSetEvent. Resolution is one millisecond, and CPU usage does not increase. The attached executable needs SSE2 (sorry Michael :()

include \masm32\MasmBasic\MasmBasic.inc ; http://www.masm32.com/board/index.php?topic=12460
uselib winmm
CbTimer PROTO:DWORD,:DWORD,:DWORD,:DWORD,:DWORD

.data?
Counter SDWORD ?
Ticks dd ?
TimerID dd ?

Init

Open "O", #1, "TimerTest.txt"
mov Counter, 10000 ; will run 10 seconds, enough to check CPU usage
mov Ticks, Timer()
mov TimerID, rv(timeSetEvent, 1, 1, CbTimer, 0, TIME_PERIODIC or TIME_KILL_SYNCHRONOUS)
.if eax
.Repeat
invoke Sleep, 100
.Until Counter<=0
.endif
Close

Inkey Str$("\n\nYour puter has run %3f hours since the last boot, give it a break!", Timer()/3600000)
Exit

CbTimer proc ID:DWORD, uMsg:DWORD, dwUser:DWORD, dw1:DWORD, dw2:DWORD
  dec Counter
  .if Sign?
invoke timeKillEvent, TimerID
  .else
mov ecx, Timer()
sub ecx, Ticks
Print #1, Str$(Counter), Tb$, Str$(ecx), CrLf$
  .endif
  ret
CbTimer endp
end start

clive

Quote from: jj2007
The authors are probably wrong about the 100ns.

The resolution of the time base used by Microsoft (FILETIME) is 100 ns, the granularity of the updates are going to be significantly higher. With all these timer constructs, the event occurs when the system identifies that all the delay has been exhausted, not at the time requested. With the granularity, you don't even know the time you actually started with any real precision. What you really need is a free running hardware counter that is clocking at a known/stable frequency, ideally disciplined with GPS, NTP or IEEE-1588.

ie

CurrentTime += 5000; (CurrentTime - StartTime) >= TimeOut;

StartTime could also be set at tick 0 .. 4999

or

CurrentTime += 5000; (CurrentTime - TargetTime) >= 0;

The specific trick with video frames is not to let time slip/drift accumulate. You get the time at the beginning of playback, and increment the target time at the frame rate, and achieve addition discipline from the audio (known/stable frequency, but probably *not* synchronous to your system timebase).

The time of any specific Sleep(), or whatever method, should be irrelevant.
It could be a random act of randomness. Those happen a lot as well.

jj2007

Clive,
My previous posts uses the MM timer, which has the required features for a more or less stable 1 ms resolution. See sample output below. The left column is the counter for Print #1, the second one is the elapsed GetTickCount since launching the timer.

9999 0
9998 0
9997 0
9996 0
9995 0
9994 0
9993 0
9992 0
9991 0
9990 0
9989 0
9988 0
9987 0
9986 15
9985 15
9984 15
9983 15
9982 15
9981 15
9980 15
9979 15
...
18 9968
17 9984
16 9984
15 9984
14 9984
13 9984
12 9984
11 9984
10 9984
9 9984
8 9984
7 9984
6 9984
5 9984
4 9984
3 9984
2 9984
1 10000
0 10000

oex

These messages have already illuminated a glaringly obvious mistake in my code.... I was using GetTickCount in conjunction with Sleep to check if I was into the next time frame :/.... Thanks guys for your help you have saved me milliseconds!!!! :bg
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

joemc

you may wish to check out VideoLAN's VLC player.  it is open source if you wish to see how they implement video.

oex

E^Cube suggested NtDelayExecution (also 100ns) on another post, thought I might add a note this has been very useful info for me
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv