Exetools  

Go Back   Exetools > General > General Discussion

Notices

Reply
 
Thread Tools Display Modes
  #1  
Old 09-01-2010, 23:06
Enigma Enigma is offline
Developer
 
Join Date: Oct 2009
Posts: 30
Rept. Given: 0
Rept. Rcvd 23 Times in 8 Posts
Thanks Given: 0
Thanks Rcvd at 7 Times in 7 Posts
Enigma Reputation: 23
GetTickCount lies??

Hi guys!

Have faced some very interesting problem with GetTickCount.

Imagine I placed to the thread, in some endless loop, such code:
Code:
x = GetTickCount;
Sleep(1000);
x = GetTickCount - x;
What do you think the "x" contains? Usually this is value >= 1000, but sometimes it is 999, and more curious, sometimes it is 998. Tested with 997 and looks like this never happens.

Do you know why after 1000 milliseconds sleep GetTickCount shows 998 milliseconds difference?
Reply With Quote
  #2  
Old 09-01-2010, 23:47
BoB's Avatar
BoB BoB is offline
Lo*eXeTools*rd
 
Join Date: Jun 2009
Location: England
Posts: 85
Rept. Given: 88
Rept. Rcvd 56 Times in 24 Posts
Thanks Given: 2
Thanks Rcvd at 2 Times in 2 Posts
BoB Reputation: 56
Sure it is not the Sleep function that lies?
Reply With Quote
  #3  
Old 09-02-2010, 05:28
Git's Avatar
Git Git is offline
Old Git
 
Join Date: Mar 2002
Location: Torino
Posts: 1,116
Rept. Given: 220
Rept. Rcvd 265 Times in 157 Posts
Thanks Given: 110
Thanks Rcvd at 220 Times in 126 Posts
Git Reputation: 200-299 Git Reputation: 200-299 Git Reputation: 200-299
On a determinate real-time operating system, it should return 1000 every single time without fail. Windows is not a determinate real-time operating system, so the value cannot be guaranteed. it's theoretically possible that the second call never occurs, and if/when it is called it could be at any priority level, with any number of other processes competing for CPU time at both higher and lower priorities.

Git
Reply With Quote
  #4  
Old 09-02-2010, 22:55
Enigma Enigma is offline
Developer
 
Join Date: Oct 2009
Posts: 30
Rept. Given: 0
Rept. Rcvd 23 Times in 8 Posts
Thanks Given: 0
Thanks Rcvd at 7 Times in 7 Posts
Enigma Reputation: 23
To BoB I do not what functions lies...

To Git I'm using usual PC with Win 7 x64, not under VMware and so on...

So do you think it is normal? And what other results do you think we could get after Sleep(1000)? Looks like it is quite unstable code and sometimes we could get 900 and even 1 :8 ?
Reply With Quote
  #5  
Old 09-03-2010, 01:07
oVERfLOW oVERfLOW is offline
Family
 
Join Date: Jan 2005
Location: Tehran
Posts: 117
Rept. Given: 127
Rept. Rcvd 42 Times in 19 Posts
Thanks Given: 2
Thanks Rcvd at 5 Times in 5 Posts
oVERfLOW Reputation: 42
@Git

Theoretically
A Real Time System must return Exactly 1000
But a non Real Time system shouldn't return a value less than 1000 but more than 1000

I think it's a algorithm related problem caused by Sleep function.
Reply With Quote
  #6  
Old 09-03-2010, 19:32
Git's Avatar
Git Git is offline
Old Git
 
Join Date: Mar 2002
Location: Torino
Posts: 1,116
Rept. Given: 220
Rept. Rcvd 265 Times in 157 Posts
Thanks Given: 110
Thanks Rcvd at 220 Times in 126 Posts
Git Reputation: 200-299 Git Reputation: 200-299 Git Reputation: 200-299
I see your point overflow, but thinking about it, couldn't the GetTickCount() function get robbed of CPU time and hence run slow?. All depends how it is implemented. If it reads a real time clock, or is interrupt driven then it should never return a low count. If it is just a queued task bumping a counter I think it could. In this example, the same applies to the Sleep() function.

Git
Reply With Quote
The Following User Gave Reputation+1 to Git For This Useful Post:
oVERfLOW (09-04-2010)
  #7  
Old 09-04-2010, 18:12
gigaman gigaman is offline
Friend
 
Join Date: Jun 2002
Posts: 87
Rept. Given: 0
Rept. Rcvd 3 Times in 2 Posts
Thanks Given: 0
Thanks Rcvd at 14 Times in 11 Posts
gigaman Reputation: 4
You cannot rely on any exact timing on Windows - it's not a real-time OS.
A context switch may always occur in the middle of your code, delaying it significantly. For example, you call the first GetTickCount, then Sleep - and after the Sleep function returns (and before the second GetTickCount is called), your process loses the CPU, another running process uses it for a while (say 20ms to the next timeslice), and then you get it back - so it looks like your Sleep actually took 20ms longer.
[OK, I know this scenario is quite unlikely with this particular code, because you'd probably get a full timeslice after Sleep, but it's just to illustrate the point].

As for why it should be less than 1000 ms... even the today's hardware doesn't make it easy for exact timing. With all those turbo modes (the CPU frequency gets temporarily increased under load) and power saving features (the CPU clock is reduced if not under heavy load - especially on mobile devices), it's very hard to measure time exactly.

VirtualDub's author wrote about it years ago: http://virtualdub.org/blog/pivot/entry.php?id=106
Reply With Quote
The Following User Gave Reputation+1 to gigaman For This Useful Post:
oVERfLOW (09-06-2010)
  #8  
Old 09-04-2010, 18:26
Squidge's Avatar
Squidge Squidge is offline
Drunken Squirrel
 
Join Date: Oct 2002
Posts: 412
Rept. Given: 4
Rept. Rcvd 9 Times in 4 Posts
Thanks Given: 0
Thanks Rcvd at 6 Times in 6 Posts
Squidge Reputation: 9
It could also be that the resolution of the system clock isn't that accurate.

Did you try using timeBeginPeriod to set the timer resolution ?

Don't forget that Sleep works by creating a thread to release the remainder of your time slice, which also involves delays.
Reply With Quote
  #9  
Old 09-05-2010, 06:42
dila dila is offline
Friend
 
Join Date: Jan 2010
Posts: 60
Rept. Given: 12
Rept. Rcvd 32 Times in 14 Posts
Thanks Given: 35
Thanks Rcvd at 74 Times in 20 Posts
dila Reputation: 32
MSDN says: "The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds.".

For Sleep(1000) that would give a min time of 984 and a max of 1016.

That does not include the call/ret overhead for the Sleep/GetTickCount functions.

Last edited by dila; 09-05-2010 at 06:44. Reason: Math error
Reply With Quote
  #10  
Old 09-05-2010, 16:09
Enigma Enigma is offline
Developer
 
Join Date: Oct 2009
Posts: 30
Rept. Given: 0
Rept. Rcvd 23 Times in 8 Posts
Thanks Given: 0
Thanks Rcvd at 7 Times in 7 Posts
Enigma Reputation: 23
gigaman - thanks you very much for the very helpful reply!

Now this problem is more clear for me, thanks!

To dila - good MS note, but the word "typically" is very confusing typically 16 ms, but sometimes it could have more differences.
Reply With Quote
  #11  
Old 10-04-2010, 18:17
LaDidi LaDidi is offline
VIP
 
Join Date: Aug 2004
Posts: 222
Rept. Given: 2
Rept. Rcvd 11 Times in 10 Posts
Thanks Given: 64
Thanks Rcvd at 54 Times in 29 Posts
LaDidi Reputation: 11
@Enigma:
The resolution is approximatively 10 ms for uniproc and 15 (15,625) ms for multi.
Check it wih ClockRes from SysInternals.
INT 1a use it's 65536 / 1193180 ie # 0,055 s

Regards.
Reply With Quote
  #12  
Old 10-18-2010, 22:05
memo-5 memo-5 is offline
Friend
 
Join Date: Sep 2005
Posts: 84
Rept. Given: 15
Rept. Rcvd 3 Times in 3 Posts
Thanks Given: 64
Thanks Rcvd at 11 Times in 6 Posts
memo-5 Reputation: 3
Hi
You could try multimedia timers it's more accurate and has higher resolution.
good luck
Reply With Quote
Reply

Tags
sleep, time


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



All times are GMT +8. The time now is 03:09.


Always Your Best Friend: Aaron, JMI, ahmadmansoor, ZeNiX, chessgod101
( Since 1998 )