Recent

Author Topic: The time in Sleep is wrong, + 1  (Read 8301 times)

zanden30@hetnet.nl

  • New Member
  • *
  • Posts: 12
The time in Sleep is wrong, + 1
« on: November 22, 2018, 11:37:03 am »
The implementation on Sleep ( t ) , t [mS] is wrong.
t = 0 gives 0 mS sleep. OK.
But any other value gives (t + 1) mS of sleep.
Hence, it is impossible to Sleep 1 mS.

By the way: on Windows 10 the sleep time is on average far within 5% precise, much better than suggested in the documentation. Not too bad……

tr_escape

  • Sr. Member
  • ****
  • Posts: 432
  • sector name toys | respect to spectre
    • Github:
Re: The time in Sleep is wrong, + 1
« Reply #1 on: November 22, 2018, 11:48:08 am »
I tested in windows 10 Lazarus 1.9.0 rFRET_UNKNOWN_REVISION FPC 3.1.1 i386-win32-win32/win64

By the code:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. uses SysUtils;
  3. var
  4.   first,last : TDateTime;
  5. begin
  6.   first:=Now;
  7.   Sleep(1);
  8.   last:=Now;
  9.   WriteLn('Between : '+FormatDateTime('hh:nn:ss.zzz',last-first));
  10.   ReadLn;
  11.  
  12. end.
  13.  

It is gives 00:00:00.001 or 00:00:00.002, I think it is up to OS busyness time.


marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 11383
  • FPC developer.
Re: The time in Sleep is wrong, + 1
« Reply #2 on: November 22, 2018, 11:48:31 am »
So what OS is this?

Afaik Sleep(x) sleeps AT LEAST x ms. Then it might take another context switch to activate the thread and get it running. Such latencies are often CPU dependent.

440bx

  • Hero Member
  • *****
  • Posts: 3946
Re: The time in Sleep is wrong, + 1
« Reply #3 on: November 22, 2018, 12:05:30 pm »
So what OS is this?

Afaik Sleep(x) sleeps AT LEAST x ms. Then it might take another context switch to activate the thread and get it running. Such latencies are often CPU dependent.
Not to mention highly OS dependent.   
(FPC v3.0.4 and Lazarus 1.8.2) or (FPC v3.2.2 and Lazarus v3.2) on Windows 7 SP1 64bit.

Thaddy

  • Hero Member
  • *****
  • Posts: 14206
  • Probably until I exterminate Putin.
Re: The time in Sleep is wrong, + 1
« Reply #4 on: November 22, 2018, 12:12:57 pm »
T=0 is a special case on windows and means "give up timeslice". See msdn https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-sleep
And indeed, it is highly platform dependent. It requires a RTOS to reliably get the exact value.
« Last Edit: November 22, 2018, 12:15:28 pm by Thaddy »
Specialize a type, not a var.

zanden30@hetnet.nl

  • New Member
  • *
  • Posts: 12
Re: The time in Sleep is wrong, + 1
« Reply #5 on: November 22, 2018, 02:45:05 pm »
No, no, it is really no latency.
When I chose 1 mS ==> 2 mS
When I chose 10 mS ==> 11 mS.
When I chose 19 mS ==> 20 mS (corrected, excuse me).
And the values measured are very precise. When I count 1.000 times, the deviation is only < 1%
So I think there is a while loop coding error in this FPC procedure. Or in Windows, also possible, of course. Can I check that?
The latency is only some uSeconds.

« Last Edit: November 23, 2018, 02:19:56 am by zanden30@hetnet.nl »

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: The time in Sleep is wrong, + 1
« Reply #6 on: November 22, 2018, 02:52:48 pm »
When I chose 1 mS ==> 2 mS
When I chose 10 mS ==> 11 mS.
When I chose 19 mS ==> 10 mS.
I take it that last 10 mS is a typo.

Anyway... how do you calculate those mS? Maybe the time for calculating the difference in time also takes 1 mS. So your result will always be 1 mS above the selected Sleep().

And as said. Sleep is not that accurate. This is what Microsoft says about it (for Windows):
Quote
If dwMilliseconds is greater than one tick but less than two, the wait can be anywhere between one and two ticks, and so on.
« Last Edit: November 22, 2018, 02:54:27 pm by rvk »

lucamar

  • Hero Member
  • *****
  • Posts: 4219
Re: The time in Sleep is wrong, + 1
« Reply #7 on: November 22, 2018, 03:12:56 pm »
[...] And the values measured are very precise. When I count 1.000 times, the deviation I only < 1%

It can't be measured very precisely because the nature of Sleep. Think of it as if it where an abbreviation of SleepForAtLeast(ms); a small deviation of 1 to 5 ms (depending on the parameter and the system load) should be expected in almost all architectures.
« Last Edit: November 22, 2018, 03:14:47 pm by lucamar »
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

Martin_fr

  • Administrator
  • Hero Member
  • *
  • Posts: 9794
  • Debugger - SynEdit - and more
    • wiki
Re: The time in Sleep is wrong, + 1
« Reply #8 on: November 22, 2018, 03:44:12 pm »
By the way: on Windows 10 the sleep time is on average far within 5% precise, much better than suggested in the documentation. Not too bad……


The doc may be worst case. On most modern computers the CPU is fast enough, and has enough cores, so an active (focused) user process will not get much interruption.

If of course, I run any such code on my 12 year old (standby) 32bit system.... I bet the story changes.

Anyway the conclusion is:
- "sleep" is not meant to be exact. It is meant "at least the given time"
- Even if "sleep" were exact, the OS does not guarantee your process will not be interrupted. Your app could at any time (including just before/after a sleep) be interrupted for any amount of time.

 

rvk

  • Hero Member
  • *****
  • Posts: 6111
Re: The time in Sleep is wrong, + 1
« Reply #9 on: November 22, 2018, 04:02:21 pm »
And also when measuring elapsed time you shouldn't rely on Now or GetTickCounter or likewise. Those are not accurate within 1ms (although they result in 1ms values).

You should use something like QueryPerformanceCounter (or equivalent for Linux).

You might want to look into EpikTimer.

zanden30@hetnet.nl

  • New Member
  • *
  • Posts: 12
Re: The time in Sleep is wrong, + 1
« Reply #10 on: November 23, 2018, 02:15:52 am »
I have measured with the Now function. This is as far as I can see connected with the Win10 system clock, date time, which is very precise. Of course there is a standard deviation due to interrupts. But on average, when I measure 1.000 or even 10.000 times, it reproduces the same values.

When I measured my mainloop with the Now function I could see that a heavy CPU load degraded, or course, the throughput; and also here I measured rather stable and logical values with the Now function with a low load of the CPU (4 cores).

I have measured the loop and measurement itself. That takes only 1 uS per loop. So there is a negligible bias by the measurement (< 1 0/00).
It is too accidentally, that the time is always exactly (exactly!!!) 1 mS too much. Must be a mistake; either in the FPC implementation or in the Win 10 system call. I have no idea how I can check both of them. But I am sure that guys in this forum can do…..




zanden30@hetnet.nl

  • New Member
  • *
  • Posts: 12
Re: The time in Sleep is wrong, + 1
« Reply #11 on: November 23, 2018, 02:25:26 am »
I tested in windows 10 Lazarus 1.9.0 rFRET_UNKNOWN_REVISION FPC 3.1.1 i386-win32-win32/win64

By the code:

Code: Pascal  [Select][+][-]
  1. program Project1;
  2. uses SysUtils;
  3. var
  4.   first,last : TDateTime;
  5. begin
  6.   first:=Now;
  7.   Sleep(1);
  8.   last:=Now;
  9.   WriteLn('Between : '+FormatDateTime('hh:nn:ss.zzz',last-first));
  10.   ReadLn;
  11.  
  12. end.
  13.  

It is gives 00:00:00.001 or 00:00:00.002, I think it is up to OS busyness time.



I think one measurement does not indicate much. Especially not when the duration of the time equals the resolution. That is a "non-measurement".

I repeat the measurement 1.000 and more times, which gives a valuable, accurate and reproducible result.

« Last Edit: November 23, 2018, 02:30:01 am by zanden30@hetnet.nl »

tr_escape

  • Sr. Member
  • ****
  • Posts: 432
  • sector name toys | respect to spectre
    • Github:
Re: The time in Sleep is wrong, + 1
« Reply #12 on: November 23, 2018, 06:06:53 am »
I think one measurement does not indicate much. Especially not when the duration of the time equals the resolution. That is a "non-measurement".

I repeat the measurement 1.000 and more times, which gives a valuable, accurate and reproducible result.


I would like to look your measurement codes, could you please share with us?
« Last Edit: November 23, 2018, 06:21:30 am by tr_escape »

Thaddy

  • Hero Member
  • *****
  • Posts: 14206
  • Probably until I exterminate Putin.
Re: The time in Sleep is wrong, + 1
« Reply #13 on: November 23, 2018, 10:15:18 am »
On most platforms including windows, the sleep call is a direct call to the OS, so it can't be a Freepascal issue anyway.
Code: Pascal  [Select][+][-]
  1. procedure Sleep(dwMilliseconds:DWORD); external 'kernel32' name 'Sleep';
« Last Edit: November 23, 2018, 10:29:05 am by Thaddy »
Specialize a type, not a var.

User137

  • Hero Member
  • *****
  • Posts: 1791
    • Nxpascal home
Re: The time in Sleep is wrong, + 1
« Reply #14 on: November 23, 2018, 10:18:00 am »
That's a simple example to change:
Code: Pascal  [Select][+][-]
  1. program Project1;
  2.  
  3. uses SysUtils;
  4. Const TRIES = 1000;
  5. var first, last: TDateTime;
  6.     i: integer;
  7. begin
  8.   first:=Now;
  9.   for i:=1 to TRIES do Sleep(1);
  10.   last:=Now;
  11.   WriteLn('Between: '+FormatDateTime('hh:nn:ss.zzzz',(last-first)/TRIES));
  12.   WriteLn('Duration: '+FormatDateTime('hh:nn:ss.zzzz',last-first));
  13.   ReadLn;
  14. end.
Gives this on Win10-64bit:
Code: Pascal  [Select][+][-]
  1. Between: 00:00:00.002
  2. Duration: 00:00:01.904

 

TinyPortal © 2005-2018