BBC BASIC for Windows
Programming >> Sound, Music and Video >> Using a high precision timer? http://bb4w.conforums.com/index.cgi?board=multimedia&action=display&num=1261793800 Using a high precision timer?
Post by 19Grumpah42 on Dec 26th, 2009, 01:16am
[Multimedia seems to be the closest fit for accurate timers.]
I think I need a more accurate clock than is provided by... : SYS "SetTimer", @hwnd%, 101, period%, 0 : MSDN says that although this is a millisecond timer, it has an expected error of 10-16 millisec. This possibly explains the lousy S.D. I am getting when timing a million iterations of one line code (e.g. 1.% for the FOR loop, 4-8% for a computed trig function within the loop) in the executable. {I am giving the *.exe full run of two CPUs at "above normal priority" with no significant conflicting tasks active, and I cannot see any R/W activity to the TEMP or TMP directories.}
I have looked (APIViewer 2004, MSDN) at ... SYS "QueryPerformanceFrequency", Frequency{} TO frequency% :REM large integer
SYS "QueryPerformanceCounter", PerformanceCount{} TO tick% :REM large integer : These both return large integers, and it is so long since I worked with lsb/msb type data that I have "lost my grip", and I'm not sure how that applies in a 32-bit OS anyway.
Could anyone offer code snippets which would let me use the allegedly much more precise timers available at system level? I would appreciate any offers, or guidance. MSDN indicates that using the system timer may be difficult to port across M/Bs because different BIOS use different ways to offer a system clock! It would be nice to avoid -- or compensate in the code -- for any such problems.
Thanks, in advance, dear BB4W gurus. --Grahame
Re: Using a high precision timer?
Post by admin on Dec 26th, 2009, 09:37am
Quote:
Could anyone offer code snippets which would let me use the allegedly much more precise timers available at system level?
For a start Windows isn't a real-time Operating System, so no matter what you do it's impossible to achieve really accurate, consistent, timings. If that's what you need, Windows simply isn't the right platform.
SYS "QueryPerformanceCounter" will give you the most accurate values available in Windows, but what you need to be aware of is that from time to time kernel interrupts will occur, or the OS will switch context to another thread (even if you've set your priority as high as you can), so when that happens the value returned will be higher than the true duration.
Beware using SYS "QueryPerformanceCounter" on a multi-processor PC because you'll get meaningless answers if your thread is switched between processors (if you're really keen you can set the processor affinity - either in Task Manager or in your own code - to prevent that happening).
If you're timing a repetitive operation, that you know must always take exactly the same time, you may be able to improve on the accuracy by making multiple measurements and assuming that the true duration is approximately the minimum value you measure.
What sort of timing accuracy do you need anyway? You should be able to get reasonably reliable results to a resolution of a millisecond simply by using SYS "timeGetTime", which doesn't suffer from the complications of QueryPerformanceCounter:
Code:
SYS "timeGetTime" TO T%
Richard.
Re: Using a high precision timer?
Post by 19Grumpah42 on Dec 27th, 2009, 01:50am
Thanks for the very prompt reply. I will go with SYS "timeGetTime" TO T%, as you suggest. I confess it never occurred to me to scroll for a Get function under the "t"s.
Thanks for pointing out about kernel interrupts under Windows.
One programme is all *FLOAT 64 operations, this naturally splits itself approximately(!) 50% between two CPUs if I let it (the sum is never more than 98%).
The idea of doing replicates and taking the shortest one for real sounds right. The functions I am measuring are less than a few hundred nanoseconds long, so I have to replicate them in a loop. I find that if I do 10^6 replicates, then using time%=TIME ,FOR loop, result=TIME-time% gives me 90% limits of +/- 12 millisec. Sounds as though the SYS call will get me about 10x better than that, which will be fine.
I now appreciate the "non real time" nature of Windows better, thanks for the guidance.