?
Solved

Implementing timing control in loop

Posted on 2000-03-25
6
Medium Priority
?
288 Views
Last Modified: 2010-04-02
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
Comment
Question by:mych
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
6 Comments
 
LVL 3

Expert Comment

by:ufolk123
ID: 2657935
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
 

Expert Comment

by:nisa
ID: 2657941
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
 

Author Comment

by:mych
ID: 2659256
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 3

Expert Comment

by:ufolk123
ID: 2659464
You can use the QueryPerformanceCounter() and QueryPerformanceFrequency() .Usage may be little bit differnt from that of SetTimer().
0
 

Accepted Solution

by:
nisa earned 200 total points
ID: 2659487
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
 
LVL 1

Expert Comment

by:the_bikeman
ID: 2662313
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

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

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

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
The goal of this video is to provide viewers with basic examples to understand and use pointers in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

718 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