Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 292
  • Last Modified:

Implementing timing control in loop

I would like to iterate a loop, say once every few milliseconds. I tried using Sleep to do it. However, upon printing out the time using GetTickCount(), I notice that the timing interval is always rounded up to the next 10 milliseconds.

For example, if the code is something like the following.

for(i = 1; i <= 100; i++)
{
tickcount = GetTickCount();
printf("\n%lu",tickcount);
Sleep(25);
}

The printed result would be something like:
xxx12
xxx42
xxx72
and so on. That is, whether I put Sleep(21), Sleep(22) or whatever, the interval would never be accurate to the millisecond but would be rounded up to the next 10 milliseconds.

Is there any way to implement some timing control so that it is more accurate?


0
mych
Asked:
mych
1 Solution
 
ufolk123Commented:
Windows is not supposed to give you a real time response.As it is not a RTOS.There can be lot of dependencies on system load and priorties etc which can affect the exact timings you may be expecting.


0
 
nisaCommented:
Hi,
  Your question are too general as the timing (ie accuracy etc) depends on the systems used. What platform are using WINNT? WIN9x? or someother Oses? How about hardware ..? 386?486?Pentium.? or some other processors(because different hardware have different realtime clock).

Anyway, generally.. GetTickCount() will give u a value the way your system define 1 tick. Ie.. if your one tick is 10 milliseconds then your realtime clock is updated every 10 milliseconds (in every timer interrupt) and to increase the accuracy u would have to reduce it(but you have to pay penalty where timer interrupts occur more frequent and might slow down other processes).

Other things is that your method is *not* suitable for measuring accurate time granularity since, If you are in multitasking env. then your timing loop may get *preempted* by a higher prority tasks or interrupt. And the task may take cpu time longer than you expected. Also, in many system(ie WINNT, WIN9x) the interrupt lantency is resonably *high*.

The better way is to use a high resolution timer routines supplied by your system(if any :)) and used the elapsed time to increment your time. In this way, your timer will be *least* affected by problem mention above.

Hope this helps.

Best Regards,
Nisa.      
0
 
mychAuthor Commented:
Hi Nina,
Can you give some examples of high resolution timer routines supplied by the system? By the way, I'm using WinNT on Pentium III.
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
ufolk123Commented:
You can use the QueryPerformanceCounter() and QueryPerformanceFrequency() .Usage may be little bit differnt from that of SetTimer().
0
 
nisaCommented:
Hi,


This Info was extracted from MSDN Library October 1999. *But* I have to remind you that it is virtual *impossible* to achive a *very* accurate timing on Normal WINNT (unless you are using Real Time Extension of WINNT or some other real time oSes).


High-Resolution Timer
----------------------

A counter is a general term used in programming to refer to an incrementing variable. Some systems include a high-resolution performance counter that provides high-resolution elapsed times.

If a high-resolution performance counter exists on the system, the QueryPerformanceFrequency function can be used to express the frequency, in counts per second. The value of the count is processor dependent. On some processors, for example, the count might be the cycle rate of the processor clock.

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter (if one exists on the system). By calling this function at the beginning and end of a section of code, an application essentially uses the counter as a high-resolution timer. For example, suppose that QueryPerformanceFrequency indicates that the frequency of the high-resolution performance counter is 50,000 counts per second. If the application calls QueryPerformanceCounter immediately before and immediately after the section of code to be timed, the counter values might be 1500 counts and 3500 counts, respectively. These values would indicate that .04 seconds (2000 counts) elapsed while the code executed.

 
//-------------------------------------

QueryPerformanceFrequency
-------------------------

The QueryPerformanceFrequency function retrieves the frequency of the high-resolution performance counter, if one exists. The frequency cannot change while the system is running.

BOOL QueryPerformanceFrequency(
  LARGE_INTEGER *lpFrequency   // current frequency
);

Parameters
----------

lpFrequency

[out] Pointer to a variable that receives the current performance-counter frequency, in counts per second. If the installed hardware does not support a high-resolution performance counter, this parameter can be zero.
Return Values
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. For example, if the installed hardware does not support a high-resolution performance counter, the function fails.

Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Windows CE: Requires version 2.0 or later.
  Header: Declared in winbase.h; include windows.h.
  Library: Use kernel32.lib.


//-------------------------------------

QueryPerformanceCounter
-----------------------

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter, if one exists.

BOOL QueryPerformanceCounter(
  LARGE_INTEGER *lpPerformanceCount   // counter value
);

Parameters
-----------
lpPerformanceCount

[out] Pointer to a variable that receives the current performance-counter value, in counts. If the installed hardware does not support a high-resolution performance counter, this parameter can be zero.
Return Values
If the installed hardware supports a high-resolution performance counter, the return value is nonzero.

If the function fails, the return value is zero. To get extended error information, call GetLastError. For example, if the installed hardware does not support a high-resolution performance counter, the function fails.

Remarks
On a multiprocessor machine, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the BIOS or the HAL. To specify processor affinity for a thread, use the SetThreadAffinityMask function.

Requirements
  Windows NT/2000: Requires Windows NT 3.1 or later.
  Windows 95/98: Requires Windows 95 or later.
  Windows CE: Requires version 2.0 or later.
  Header: Declared in winbase.h; include windows.h.
  Library: Use kernel32.lib.



Best Regards,

Nisa.
0
 
the_bikemanCommented:
I'm not sure if this will be of any help, but if you are using gcc you can include time.h, and use the rawclock() functions.  It operates on 91.02 (rounded to 91) ticks per second.  Just a thought....

the_bikeman
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now