One millisecond resolution is not enough!

Posted on 1998-09-20
Last Modified: 2010-04-06
I am not very familiar with the internal workings of Windows, or the Windows API.  I know that in DOS you could easily manipulate the timer interrupt. How do you go about doing that in Delphi, or Windows in general?  Is it being unreasonable to set a timer at 1 MHz?

(note: I know about TTimer)
Question by:scrapdog

Expert Comment

ID: 1340316
Here is something(timer, I mean) with resolution 0.1 msec:
Z-timer on Delphi Super Page:
as the matter of fact I couldn't get it to work, co if you succeed, leave a comment how ;-)

Author Comment

ID: 1340317
Thanks for the tip.  I looked at the source code, and even though a lot of it confuses me (not the assembly code, but the windows functions), I will learn something by looking at it.  However, a component wasn't really what I was looking for.

I will elaborate of my question a little more.  The program PC64 for Windows emulates a Commodore 64, which is a computer that runs at about 1 MHz.  In order to execute instructions cycle-exact, some timing mechanism that runs at 1 MHz must be present in the program to carry out operations in the CPU.  

Or do emulation programs generally carry out a batch of instructions? (i.e. execute a batch of 1000 instructions every millisecond)

If the latter is the case, it is because it is not possible to set a timer to 1 MHz.  If it clearly is not possible to set a timer to that rate, I would like to know.

Other applications that use a timer with a very high resolution are applications that process sound.  Do sound applications use Timers with resolutions up to 44 KHz, or do they all use a Timer with an interval of 1 msec or more with buffers?  The question is not how to do it with buffers, the question is whether buffers MUST be used.

The main thing I am trying to get at:  is it typical for applications, including emulators and multimedia, to use timers of resolution much better than 1 msec?  And if so, how?

Thanks again to duke_n for his prompt reply.
LVL 20

Expert Comment

ID: 1340318

in windows it is dangerous to trust in lowlevel timers because windows is a multitasking system. Windows decides which application gets how much cpu time. So if Windows thinks that there is an application that is more important than yours, you'll get problems with the timers.
The better way is to use the "Application.Idle" event and asking win API "GetTickCount" in the event handler of this event.

Regards, Madshi.
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.


Expert Comment

ID: 1340319
Timers in NT and Win95+ are not a nice experience if your objective is other than to move around icons on the desktop. There is no good way to implement hires timers. Not even with kernelmode drivers.
Sound applications generally use buffers.
The multimedia timers (timeSetEvent) only have 1 millisecond resolution (not including timer latency).

Check QueryPerformanceCounter for very high granularity timers under NT.

/// John

Author Comment

ID: 1340320
So it is safe to assume that all emulation programs (such as PC64) execute instructions in a batch?

LVL 20

Expert Comment

ID: 1340321
I'm quite sure that these emulation programs does NOT install a timer at the cpu frequence of the emulated cpu. So they will have to use something like batch instructions...

Regards, Madshi.

Accepted Solution

wamoz earned 50 total points
ID: 1340322
High resolution timing under Windows is done using the Multimedia Timer Functions. If these aren't good enough then you have to build some custom hardware.

In the case of your "cycle-exact" emulator, I think you will find that it isn't cycle exact. What is most likely happening is that it is running rather faster than a C64, and every so often idles until the correct amount of time has elapsed.

Madshi sensibly warns you against trusting timers due to the pre-emptive nature of multi-tasking operating systems. There are three things you can do about this.

(1) Design your code on the expectation that it will occasionally miss a beat (literally) so that it doesn't matter. This is how streaming audio copes with packet loss and timing problems - it just drops late packets and plays whatever turns up exactly when the clock says they should be played.

(2) You can increase the priority of a thread to real-time, the purpose of which is self evident.

(3) Cut your code some slack. Size the batches of instructions (I refer to your own comment) so that their duty cycle is less than half of what is theoretically supported. When working this out, don't forget that there are other processes running.

I gather you want to do this sort of thing yourself. Boy have you jumped in at the deep end. Nevertheless, there's only one way to learn. If I wanted to do this I'd structure it as described in the previous paragraph. Controlling the wait state is most efficiently done by going into an idle loop that blocks on a simple flag. (repeat ... until bSynch).

If you want this to work under Win95 or in a multi-threaded application, don't forget to process the message queue inside the loop.

You tell the loop to exit using an event handler that you fire using timeSetEvent().

With respect to multimedia devices that require high frequency operation, they employ a similar clock synching strategy. For example, your sound card and your CPU dance an elaborate dance with the CPU bursting wave tables and and timing *descriptions* across a DMA channel in response to "more" requests expressed by the sound card using an interrupt and memory mapped I/O.

The following functions are used with multimedia timers. Most of these are documented to some degree in the Delphi help but if that's not enough I can furnish you with detailed APIs.


Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
A short film showing how OnPage and Connectwise integration works.

930 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now