Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Visual Basic capabilities/recommendations 1

Status
Not open for further replies.

aarrgghh

Technical User
Sep 5, 2002
60
US
I am researching the capabilities of visual basic. I need to know if visual basic has any real-time timing (in milliseconds) abilities. The accuracy of the timing needs to be high and consistent. The timing ability will be used in a reaction time test. Also, how Windows OS mobile is visual basic? Can I develop a program and test it under XP and expect it to run in the same way under, Microsoft Windows Mobile or is it like web-development in that you have to accommodate each browsers individual quarks? Any help, direction, and/or suggestions for the best way to make a simple reaction time test and have it Windows OS Mobile would be greatly appreciated. Did I mention that this program would have to be able to read and write the reaction times to a file?

Thanks
 
Unless things have changed in XP - Windows was never responsive down to the milliseconds level. Best case was around 50 ms. VB is limited to the OS.

"I think we're all Bozos on this bus!" - Firesign Theatre [jester]
 
Better than that (55 ms) is on NT 4/5 systems (10 ms) and seems to increase as time goes on.

But, Windows can mimic time elapsed way way below a micro second using GetTicCount, or better, using the QueryPerformanceCounter

Option Explicit
Private Declare Function QueryPerformanceFrequency Lib "kernel32" (lpFrequency As Currency) As Long
Private Declare Function QueryPerformanceCounter Lib "kernel32" (lpPerformanceCount As Currency) As Long

Sub TestQueryPerfomanceCounter()
Dim StartTicks As Currency
Dim StopTicks As Currency
Dim Frequency As Currency
Dim loop As Long
QueryPerformanceFrequency Frequency
QueryPerformanceCounter StartTicks

Dim loop As Long

For loop = 1 To 10000000
Next loop

QueryPerformanceCounter StopTicks
Debug.Print (StopTicks - StartTicks) / Frequency
'**********************************************

StartTicks=0
QueryPerformanceCounter StartTicks
QueryPerformanceCounter StopTicks
Debug.Print (StopTicks - StartTicks) / Frequency
End Sub


If you want real time that low you will need to purchase a third party timer.
 
>mimic time elapsed

I not sure I understand why you say 'mimic' with reference to the QueryPerformance stuff. Can you clarify?
 
Simulate a real clock, as a single unit, between seconds by using a seperate counter, counting between seconds.

The counter freq can be different on different systems, and the est freq is the number of counts between seconds - i.e. 50,000 counts per second.


 
Given that Windows is definitely not a real-time OS (some people have tried to make RT versions of NT, with varying degrees of success), and that the very nature of VB makes it an impractical tool for developing real-time applications I think it fair to say that we can never really expect a real-time response in pure Computer Science terms.

However, the requirement here seems to be much simpler: can we get timing accurate to the millisecond?

Well, let's have a look...

Windows has a number of timers and clock counters that you can theoretically use.

Firstly, what is the difference between a timer and a clock counter?

Generally, a timer is something that raises an event at specified intervals or at a given time. For an application, this event might be a callback, a windows message, or a windows event, although at the OS level we might be talking about interrupts

A clock counter is a counter which is increments at a specific 'tick rate' and can be queried for the current number of ticks that it has counted. It is important to realise that the tick rate for most of these clock counters is provided by a timer as described in the previous paragraph.

Why is this important? Because most of the common timers and clock counters are derived from or driven by the system timer - and the system timer (in theory) has a granularity that is a) lower than you might think given the claimed resolution of the various timers and clock counters b) dependant on your OS

Basically the system timer has a resolution of a little over 55ms on W95/98/Me, 16ms on NT 3.5, 10ms on NT4/2000, 10ms or 15ms on XP. I provided a brief explanation of the reasons for this in thread222-495997 (and it is worth pointing out that it is possible to modify this granularity if one is feeling really, really brave; it requires calls to some 'native' kernel functions

All the following timers and clock counters are based off the system timer:

Standard VB timer (claims 1 milliscond resolution)
SetTimer (claims 1 millisecond resolution)
SetWaitableTimer (claims 1 millisecond resolution)
GetLocalTime (claims 1 millisecond resolution)
GetSystemTime (claims 1 millisecond resolution)
GetSystemTimeAsFileTime (claims 100 nanosecond resolution!!)

and therefore their actual resolution is limited to that of the granularity of the system timer.

Indeed, it gets worse than that for the timers we've mentioned, since there is some overhead and latency in raising the event. And if it is a timer which relies on a process receiving a WM_TIMER message before the timer event will get serviced (eg the VB timer, and SetTimer) you can get even more unexpected delays, since WM_TIMER is a) a low priority message b) you can only have one WM_TIMER message in a process's message queue at a time (which means that you can actually lose timer events...)

Of course, in Windows' history there have been requirements for timings more accurate than that provided by the system timer - most notably MIDI in the multimedia extensions, which required an accuracy of real resolution of 1 millisecond. Your VB program can use this accuracy itself by accesing the multimedia timers. The most accurate way to use them is as a clock counter via timeGetTime (or timeGetSystemTime, although this latter has a slightly higher overhead); if you use them as timers (via a callback) then you will suffer a little from the latencies inherent in raising the appropiate callback.

So, using the multimedia timers as clock counters is a pretty good way of getting accurate millisecond elapsed timings.

What if we want better than that? For example, how might we time how much processor time a thread or process has actually taken up, which might often be in the sub-millisecond range? As we have seen the (current) multimedia timers have a maximum resolution of 1 millisecond, so they are clearly no good...

Here's where we introduce the ACPI timer (also known as the Power Management, or PM, clock). It is this real-time clock that normally provides info to the QueryPerformanceFrequency and QueryPerformanceCounter (and is therefore commonly better known to most people as the high performance timer). Typically the ACPI timer runs at 3.579545MHz, giving an accuracy of of about 280 nanoseconds (different hardware with different ACPI timers may give differing results). At this sort of clock resolution the overheads for retrieving the tick count (even though the ACPI timer is optimised for just that) become significant - but they pale into significance when compared to the overheads of VB. Indeed, counting the numer of times we can call QueryPerformanceCounter in a 1 second tight loop shows that the effective accuracy is reduced to about 1.5 microseconds. However, that should be a more than sufficient granularity for doing millisecond reaction timing...





 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top