views:

321

answers:

4

Guys,

Is there a simple way to determine how many milliseconds I need to "Sleep" for in order to "emulate" a 2 mhz speed. In other words, I want to execute an instruction, call System.Threading.Thread.Sleep() function for an X amount of milliseconds in order to emulate 2 mhz. This doesn't need to be exact to the millisecond, but is there a ball park I can get? Some forumlate that divides the PC clock speed by the 2 mhz or something?

Thanks

+1  A: 

A 2 MHz clock has a 500 ns period. Sleep's argument is in milliseconds, so even if you used Sleep(1), you would miss 2,000 cycles.

Worse, Sleep does not promise that it will return after X milliseconds, only that it will return after at least X milliseconds.

Your best bet would be to use some kind of Timer with an event that keeps the program from consuming or producing data too quickly.

ajs410
Allow me to clarify what I meant by "producing or consuming". Let's say you're producing images to display on the screen, for instance a video game. If you produce images too quickly, the game will feel like it runs very fast.You need to figure out what your data is, if you produce or consume, and how often. Then use a System.Timer to call you producer/consumer function.QueryPerformanceCounter is bad because you would need to track cycles and turn them into times. Sleep is bad because it won't necessarily wake up when you want it to, and you gradually lose time.
ajs410
A: 

The problem you will have is that the minimum sleep on windows seems to be about 20-50ms, so though you may put that you want to sleep for 1ms, it will wake up later, due to the fact that other processes will be running, and the time slice is quite large.

If you must have a small time such as 500ns (1/2e06 * 1000) then you will want to use DirectX, as it has a high-resolution timer, so that you can just loop until the pause is done, but, you will need to take over the computer, not allow other processes to interrupt what is going on.

James Black
DirectX isn't the only way you can get a high-resolution timer. You can also use QueryPerformanceCounter.
Robert Harvey
In fact, you can use System.Diagnostics.Stopwatch which wraps QueryPerformanceCounter internally.
bobbymcr
@Robert - I have never used that, I would just do it in DirectX, but, thank you for the comment, I will look at QueryPerformanceCounter. I just wanted to give a suggestion to do what he wants, since Thread.Sleep won't do it.
James Black
This isn't correct. The minimul sleep time can be 1ms (or even less). It depends on how fast the timer tick interrupt is running. This can vary at run time. See docs for timeBeginPeriod(). Also note that sleeping() is very VERY different from polling and looping. Sleep blocks and your thread will not use CPU cycles while asleep. Polling is a HUGE consumer of CPU cycles. Polling is is a classic performance design and implementation problem in many applications - avoid this if at all possible.
Foredecker
@Foredecker - In my experience you can tell it to sleep for 1ms, but there is a minimum time slice that each thread can get, so the time it goes from your thread, to do something for another thread and then wake your thread up will not be 1ms. The sleep time is to say wake me up no earlier than this time, not after this time exactly.
James Black
+1  A: 

For the user, a pause of less than 100 ms or so will generally be imperceptible. Based on that, instead of attempting to sleep after each instruction, you'd be much better off executing for something like 50 ms, then sleeping for an appropriate length of time, then executing for another 50 ms.

Also note, however, that most processors with a 2 MHz clock (e.g. a Z80) did not actually execute 2 million instructions per second. A 2 MHz Z80 took a minimum of four processor clocks to fetch one instruction giving a maximum instruction rate of 500 KHz.

Jerry Coffin
+1  A: 

Note that sleeping is not at all a good proxy for running code on a less capable CPU. There are many things that affect computational performance other than clock rate. In many cases, clock rate is a second or third (or 10'th) order determinate of computational performance.

Also note that QueryPerformanceCounter() while high resolution is expensive on most systems (3000 to 5000 CPU clocks in many cases). The reason is that it requires a system call and several reads from the HPET in the system's south bridge. (note, this varies by system).

Could you help us better understand what you are trying to do?

As I mentioned in my comment on James Black's answer: do not poll a timer call (like QPC or the direct X stufF). Your thread will simply consume massive amounts of CPU cycles and not let ANY thread at a lower priority run, and will eat up most of the time at its priority. Note that the NT Scheduler does adjust thread priorities. This is called 'boosting'. If your thread is boosted and hits one of your polling loops, then it will almost assuredly cause perf problems. This is very bad behavior from a system perspective. Avoid it if at all possible.

Said another way: Windows is a mult-tasking OS and users run lots of things. Be aware that your app is running in a larger context and its behavior can have system wide implications.

Foredecker
+1 for the useful info on polling.
Ian
If you application is the only one running, then polling won't be that big a deal, and if you need to do something in this short a time interval then polling may be useful. When I have done this it was in a game, so I would do other actions (checking for input, basic housekeeping) and so would check for the time difference and then if it was time start/stop music (which is when I needed this feature) or update the countdown before shutting down the computer.
James Black
Of course, there may be times when only one thing that looks like an application is running. But it will be rare that an app is the only thing running on a system that is important to the user. Most importantly, an app has no idea what is running - it is not practical to write an app to poll sometimes and not others.... how would it know when not to poll? If it is at all possible to code something to avoid polling, that's the best way to do it.
Foredecker