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

Am I right in saying SetTimer is 15ms resolution whereas Sleep is 10ms and if so how many instructions are executed in 5ms? I think 5ms is 5/1000s of a second? so that is a big difference right?

Further if I do Sleep, 0 or Sleep, 1 that is effectively Sleep, 10?
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

joemc

I may be incorrect, but windows is not a real time operating system, meaning the exact time it will take is going to vary depending on your system, and what your system is doing.

SetTimer is going to generate a message that is going to be processed by DispatchMessage either to your timer proc, or to the window with WM_TIMER message,  depending on how many messages are in that thread's queue may also affect when it is seen.  Sleep() on the other hand is going to sit right where the sleep is.... meaning it is basicly going to be limited in accuracy by context switching.

oex

OK good info and I had considered that may be part of the answer ty :bg.... my main interest is in the comparison of the functions.... whether Sleep has higher resolution to SetTimer.... Currently I use Sleep,1 in my apps however if SetTimer has the same resolution it would be a better match....


To give a bit of context I am currently using Sleep, 1 for a FPS limiter checker
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

clive

On a single CPU machine you can check the cycles burned using RDTSC.

Sleep() represents the MINIMUM amount of time you expect the OS to go do something else.

Sleep() is generally used to yield your task, and pace polling loops which would otherwise saturate the CPU. If you want to do that more effectively something like WaitForSingleObject() would be the way to go.

If you want things to run on a more linear time line, you could pull the Sleep() time in/out using GetTickCount() so the slip/drift does not accumulate. For example if you wanted to poll at 10 Hz (roughly), and the first Sleep(100) yielded 150 ms, you'd request 50 ms the next time around.
It could be a random act of randomness. Those happen a lot as well.

oex

OK so I kinda get what you're saying Clive but your experience dwarfs my understanding :lol

I want the CPU to be freed up so while the scene is displaying the CPU usage drops rather than looping at 100% CPU.... My app currently calls Sleep, 1 then checks if it is time for next frame then if not Sleep, 1 again ad infinitum....

Does WaitForSingleObject continue to beast the processor/ have better resolution....

I have used RDTSC before however I dont know how to make that yeild

EDIT: Reread and taken in what you said about RDTSC will do some testing ty for your time guys
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

clive

I come from a embedded/hardware/driver background so some of my experiences won't be too helpful.

Your biggest problem here is knowing what the Time Quantum is (amount of run time allocated to each runable thread/task, differs from OS to OS, and Workstation vs Server) and how many other threads/tasks of the same or higher priority are running. I think you'll find Windows isn't very timely when it comes to user space code. Even with timers, you are sharing a common resource and queuing for it like everyone else.  Sometimes you'll get lucky, other times you won't.

The closer you can get your Sleep() time, or WaitForSingleObject() timeout, to fall at the point you expect the "frame" to arrive the better. ie it would help you in the scheduler if your thread awakens once, rather than runs/yields a dozen times and gets pushed to the back of the list each time.

With both RDTSC and GetTickCount() permit you take snap shots and then compute the delta time. RDTSC has much finer granularity, but it comes from the CPU you are running on, and will likely be effected by things like SpeedStep or other dynamic clock throttling.

WaitForSingleObject() is designed to completely stop execution of the thread/task until either the event is signalled or the timeout expires.
It could be a random act of randomness. Those happen a lot as well.

BasilYercin


oex

Quote from: clive on May 19, 2010, 09:07:30 PM
ie it would help you in the scheduler if your thread awakens once, rather than runs/yields a dozen times and gets pushed to the back of the list each time.

Awesome, ty for your input guys.... If nothing else (and I havent had a chance to go fully through your replys yet) this will help me improve my app to some degree
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

baltoro

Here, is an old article from MSDN Magazine: Implement a Continuously Updating, High-Resolution Time Provider for Windows, 2004. It's long and tedious, but explains the difficulties involved with obtaining a highly accurate (~10 ms) time from the Windows Operating System. Clive is fairly close to the truth.   
QuoteThe problem...is that it didn't take into account the preemptiveness of the Windows NT scheduler. There is no guarantee, for example, that a thread context switch won't take place between...two lines of code, resulting in a delay of an unknown period of time.
Baltoro

oex

:lol nothing's ever simple is it..... ty baltoro that is most useful :bg
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

hutch--

oex,

In ring3 any timing technique finds accuracy limits and as you get down to intervals of about 20ms and lower it gets progressively less reliable. You can increase the accuracy with a multimedia timer but you get higher processor usage from doing it. Have a look in the masm32 example code "example10\sleepex" for the multimedia timer example.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

oex

The CPU usage is the all important factor.... I want to free up as much cpu time as possible for background tasks and my own 'get ahead' code for 3D be it decompressing images or calculating physics for the next frame.... The problem comes between frames where you want to keep the frames regular ie 33,66,100,133ms etc so you have to delay the next frame's processing.... If you loop you have 100% CPU but accuracy with RDTSC, you can also use settimer function but *I think* a loop with Sleep,1 has better accuracy (though I havent setup a testbed that assumption is just from reading random posts on the web)

If the frame takes 25ms to draw there are 8 ms just sitting there doing sweet FA.... Terribly inefficient :lol.... If Sleep has a MINIMUM resolution of 10ms you start invading on the next frames time which might take 37 ms to display so then things start messing up and you start dropping frames

It gets still worse at 60 FPS (or even 120 FPS) because you just dont have the resolution to find free time

EDIT: Not that I have the code to fill the time yet :lol but I'm working on it :bg
We are all of us insane, just to varying degrees and intelligently balanced through networking

http://www.hereford.tv

hutch--

Clocking frame rates is much the target of a multimedia timer, you can get them to run down to a few milliseconds but most animation does not require that frame rate, 20ms is 50 frames a second and from memory DVDs only run at about 28 frames a second, depends on what you are going to display. The games guys are playing with higher frame rates but they tend to work the GPU a lot harder than the CPU.

A multicore processor is the way to go if you are bashing around large amounts of video data, one thread doing diskIO while another is doing the image processing and display. Games are one area that take big advantage of dual and quad core hardware as the more threads you can maintain the more data you can move around at high speed. I would also be inclined to look at some of the SSE instructions as many of them are geared to do exactly this type of work.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

MichaelW

As far as I know the Sleep function and timers created by SetTimer both have an effective resolution of 10 or 15 milliseconds, depending on the version of Windows and/or the system hardware. On every system that I have tested the effective resolution for both was 10 milliseconds. The attachment is a test app that uses the high-resolution performance counter to compare the delay periods for Sleep(1) and Sleep(10).
eschew obfuscation

jj2007

The Microsoft. Win32. API provides 4 functions for dealing with waitable timer objects, providing very high resolution (100 nSec.)
http://www.codeguru.com/cpp/w-p/system/timers/print.php/c2837

The authors are probably wrong about the 100ns. Another road to go is timeBeginPeriod, but it increases slightly CPU usage.