Jump to content

sleep is not to accurate...


ludocus
 Share

Recommended Posts

I did a test..

First I TimerDiff't sleep(1000) 2 times

result:

1: 1003.58872426523

2: 1008.31055343626

thats 3 millie seconds wrong..

Now I made my own sleep :)

I did 2 tests with _Sleep(1000) and got the following results:

1: 1000.01117460459

2: 1000.01340952551

Very accurate!

just to let people now that sleep is not so accurate... because when someone is making something wich needs very accurate sleeping my code could be better :P

here are the tests:

$11 = _Example1()
$12 = _Example1()
$21 = _Example2()
$22 = _Example2()
msgbox ( 32, 'sleeping results', 'the results for normal sleep are:'&@CRLF&'1) '&$11&@CRLF&'2) '&$12&@CRLF&@CRLF&'The results for my _Sleep are:'&@CRLF&'1) '&$21&@CRLF&'2) '&$22)
ClipPut($11&@CRLF&$12&@CRLF&$21&@CRLF&$22)
Func _Example1() ;normal sleep
$Timer = TimerInit()
sleep(1000)
$tmp = TimerDiff($timer)
return $tmp
EndFunc

Func _Example2() ;my _Sleep
$Timer = TimerInit()
_Sleep(1000)
$tmp = TimerDiff($timer)
return $tmp
EndFunc

Func _Sleep($sTime)
    $timer=TimerInit()
    Do
        $tmp = TimerDiff($timer)
    Until $tmp >= $sTime
EndFunc
Edited by ludocus
Link to comment
Share on other sites

yeh thats true...

The standard Sleep function isn't as accurate because it just rests with a very low CPU priority/usage... so there is a timelaps between the moment it says "time is over" and the moment where the cpu gets available for this info...

I guess that if you start CPU Burn at the same time as the standard Sleep the standard one will be much more accurate.

Edited by JavaCupiX
Link to comment
Share on other sites

I found that directly calling the Sleep function in kernel32.dll was more accurate than the built in sleep:

$timer=TimerInit()
Sleep(2500)
ConsoleWrite(TimerDiff($timer)&" milliseconds"&@CRLF)

$dll=DllOpen("kernel32.dll")
$timer=TimerInit()
DllCall($dll,"none","Sleep","dword",2500)
ConsoleWrite(TimerDiff($timer)&" milliseconds"&@CRLF)

:)

Edited by monoceres

Broken link? PM me and I'll send you the file!

Link to comment
Share on other sites

The standard Sleep function isn't as accurate because it just rests with a very low CPU priority/usage... so there is a timelaps between the moment it says "time is over" and the moment where the cpu gets available for this info...

I guess that if you start CPU Burn at the same time as the standard Sleep the standard one will be much more accurate.

Using that theory, some tests:

AdlibEnable("burn", 1)

$timer = TimerInit()
Sleep (1000)
$diff = TimerDiff($timer)
MsgBox(0, "with burn - autoit "&@AutoItVersion, $diff)
ClipPut($diff)

Func burn()
    $blah = TimerDiff($timer)
EndFuncoÝ÷ Û}µÛY¨²ÖÚrH+¢éݦº ­©¬rZ,yß|ï½¼×Nºß5ãß

1000.01080577208

1000.0109460981

1000.00941788088

1000.01248233396

1000.01149270138

Average: ~1000.011 (+0.011 difference)

So the least accurate is the built-in sleep function with cpu burning, at a difference of -11.644.

The most accurate is Ludocus' sleep function at a difference of only +0.011.

The cake is a lie.www.theguy0000.com is currentlyUP images.theguy0000.com is currentlyUP all other *.theguy0000.com sites are DOWN

Link to comment
Share on other sites

  • Moderators

Having said that ... and if accuracy is very important, I'd simply adjust my sleep milliseconds accordingly to get as accurate as I could, versus sacrificing cpu usage.

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

That doesn't really work either:

$xTra = 9.708;thats what came out Theguy000's post...
ClipPut('')
For $k=1 to 2
For $i = 1 to 10
$timer = TimerInit()
Call('_Sleep'&$k, 1000)
$diff = TimerDiff($timer)
ClipPut(ClipGet()&@CRLF&';'&$diff)
Next
Next

;and the following turned out;
;#1:
;1008.4600137727
;1015.39832576487
;1018.59677696467
;1009.74397584051
;1008.8365979475
;1014.93234475331
;1031.15982617903
;1031.04528648194
;1019.196015136
;1017.63324668359
;#2:
;998.316545817974
;996.804342451345
;989.328811343341
;996.950171041292
;998.00002514286
;1015.03738603649
;1015.21897336114
;990.587351185695
;997.588240963586
;999.04820305374

Func _Sleep1($sTime)
    Sleep($sTime+$xTra)
EndFunc

Func _Sleep2($sTime)
    Sleep($sTime-$xTra)
EndFunc
Link to comment
Share on other sites

As far as using up CPU time, could one not use a hybrid method? Use the normal sleep to bring the delay within say 20ms then use the CPU intensive polling loop.

Func _Sleep($sTime)
    $timer=TimerInit()
    Sleep($sTime - 20)
    Do
        $tmp = TimerDiff($timer)
    Until $tmp >= $sTime
EndFunc

---------------------------

sleeping results

---------------------------

the results for normal sleep are:

1) 990.113547950927

2) 999.914793639974

The results for my _Sleep are:

1) 1000.02486349522

2) 1000.47743498126

---------------------------

OK

---------------------------

---------------------------

sleeping results

---------------------------

the results for normal sleep are:

1) 988.238728665235

2) 1000.61655880845

The results for hybrid _Sleep are:

1) 1000.03268571844

2) 1000.23801907784

---------------------------

OK

---------------------------

Link to comment
Share on other sites

  • 2 months later...

I found this interesting topic in someone's signature. The following script tries to correction the difference from the fastest method. It does barely anything.

Dim $mTargetWait = 100
Dim $mResult[10]
Dim $mAvDiff = 0

;; Make some test results
For $i = 0 to UBound($mResult)-1
    $lTimer = TimerInit()
    _Sleep($mTargetWait)
    $mResult[$i] = TimerDiff($lTimer)
Next

;; Calculate average difference
$lTotal = 0
For $i = 0 to UBound($mResult)-1
    $lTotal += $mResult[$i]-$mTargetWait
Next
$mAvDiff = $lTotal/UBound($mResult)
_Print($mResult, "Average difference: " & $mAvDiff, "Sleep without correction")

;; Make some test results now with correction
For $i = 0 to UBound($mResult)-1
    $lTimer = TimerInit()
    _Sleep($mTargetWait)
    $mResult[$i] = TimerDiff($lTimer)
Next

;; Calculate average difference with correction
$lTotal = 0
For $i = 0 to UBound($mResult)-1
    $lTotal += $mResult[$i]-$mTargetWait
Next
$mAvDiff = $lTotal/UBound($mResult)
_Print($mResult, "Average difference: " & $mAvDiff, "Sleep WITH correction")


;; Trying to keep _Sleep as short as possible, to not stress the interpreter
Func _Sleep($B)
    $b -= $mAvDiff
    $a = TimerInit()
    Do
    Until TimerDiff($a) >= $b
EndFunc

;; Custom print function, that makes no sense at all lulz
Func _Print($pArray, $pText, $pTitle)
    $lReturn = ""
    For $i = 0 to UBound($pArray)-1
        $lReturn &= "[" & $i & "] = " & $pArray[$i] & @CRLF
    Next
    $lReturn &= @CRLF & @CRLF & $pText
    MsgBox(0, $pTitle, $lReturn)
EndFunc
Link to comment
Share on other sites

Just a thought but to address the CPU utilization issue just stack a sleep in there but subtract a small time then use the more intensive method.

Func _Sleep($sTime)
    $timer=TimerInit()
    If $sTime > 10 Then
        Sleep($sTime - 10)
    EndIf
    Do
        $tmp = TimerDiff($timer)
    Until $tmp >= $sTime
EndFunc

--- TTFN

Link to comment
Share on other sites

Func _Sleep($sTime)
    $timer = TimerInit()

    Do
        Sleep(1)
        $tmp = TimerDiff($timer)
    Until $tmp > ($sTime * .99); .99 works well for anything over 700ms, .95 works well for anything over 65ms
        
    While $tmp < $sTime
        $tmp = TimerDiff($timer)
    WEnd
EndFunc  ;==>_Sleep

Edited by Vakari
Link to comment
Share on other sites

TimerInit and TimerDiff also take some time to calculate.

Yes, and the interpreter also takes some time to do a loop. It is all based on how much your computer is being stressed. Your best bet if you want a super accurate sleep is to absolutely kill all process and services, and run your AutoIt script that uses a dynamically corrected Sleep. You could have it do 10 loops of trying just to get it almost right.

This could potentially lead to a sleep with a variation of 0.000001s and less.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...