Jump to content

WinWaitDelay and Sleep help


Recommended Posts

API Names are case sensitive so:

    DllCall($dll, "none", "Sleep", "long", Sleep)

<{POST_SNAPBACK}>

Thanks Jon, that did it. I ran some tests, and as I suspected but not experienced enough to say, the kernel32 sleep method is essentially identical to AutoIT sleep function. This time, the actual sleep time is approximately multiples of 15 msec. The test results and code are below.

So...back to the original reason for this post...anyone know of a way to get sleep(T), accurate to +/-1 msec, low cpu useage, for small T? that I could implement until(and if) AutoIT's sleep function gets upgraded?

Here is the code and test results:

;comparing kernel32 and AutoIT sleep functions for times less than 100 msec
Dim $dll, $K, $Sleep, $SavedTimesFile = "C:\Times.csv", $TimesFileH, $KK, $JJ, $KLOOPS, $TimeData[1000], $Line = 0
$dll = DllOpen("kernel32.dll")
For $KK = 1 To 81 Step 2 ;loop without sleep to check loop time overhead
    $KLOOPS = Int(1000 / $KK) ;total time for each average would be constant if sleep function was accurate
    $T0 = TimerInit()
    For $JJ = 1 To $KLOOPS
    Next
    $Line = $Line + 1
    $TimeData[$Line] = "Loopin without sleep to show loop over head time is very small=, " & $KK & ",   " & Round(TimerDiff($T0) / $KLOOPS, 3) & " ,  " & $KLOOPS & @CR
    ConsoleWrite($TimeData[$Line])
Next
For $KK = 1 To 81 Step 2 ;sleep for various times using kernel32 sleep
    $T0 = TimerInit()
    $KLOOPS = Int(1000 / $KK)
    For $JJ = 1 To $KLOOPS
        DllCall($dll, "none", "Sleep", "long", $KK)
    Next
    $Line = $Line + 1
    $TimeData[$Line] = "DLL Call for Sleep, sleep time parameter, average sleep time, number of values in average=, " & $KK & ",   " & Round(TimerDiff($T0) / $KLOOPS, 1) & " ,  " & $KLOOPS & @CR
    ConsoleWrite($TimeData[$Line])
Next
For $KK = 1 To 81 Step 2;sleep for various times using AutoIT sleep
    $T0 = TimerInit()
    $KLOOPS = Int(1000 / $KK)
    For $JJ = 1 To $KLOOPS
        Sleep($KK)
    Next
    $Line = $Line + 1
    $TimeData[$Line] = "AutoIT Sleep, sleep time parameter, average sleep time, number of values in average=, " & $KK & ",   " & Round(TimerDiff($T0) / $KLOOPS, 1) & " ,  " & $KLOOPS & @CR
    ConsoleWrite($TimeData[$Line])
Next
$TimesFileH = FileOpen($SavedTimesFile, 2)
For $KK = 1 To $line
    FileWriteLine($TimesFileH, $TimeData[$KK])
Next
FileClose($TimesFileH)
DllClose($dll)
Exit
Here is a table of the results. Column titles are:SLEEP TIME PARAMETER

# OF LOOPS FOR AVERAGE

LOOP TIME WITHOUT SLEEP

AVERAGE AUTOIT SLEEP TIME

AVERAGE DLL SLEEP TIME

1 1000 0.01 15.6 15.6

3 333 0.005 15.7 15.6

5 200 0.006 15.6 15.6

7 142 0.006 15.6 15.6

9 111 0.006 15.7 15.6

11 90 0.006 15.6 15.6

13 76 0.006 15.6 15.6

15 66 0.006 15.6 15.6

17 58 0.007 31.2 31.2

19 52 0.007 31.2 31.3

21 47 0.008 31.3 31.2

23 43 0.065 31.3 31.2

25 40 0.007 31.3 31.3

27 37 0.007 31.3 31.2

29 34 0.016 31.2 31.3

31 32 0.007 31.2 31.2

33 30 0.008 46.8 46.9

35 28 0.007 46.8 46.9

37 27 0.008 46.9 46.9

39 25 0.008 47.1 46.9

41 24 0.007 46.8 46.9

43 23 0.008 46.9 47.2

45 22 0.007 46.8 46.5

47 21 0.008 62.4 49.9

49 20 0.008 62.5 62.4

51 19 0.008 62.5 62.5

53 18 0.009 62.5 62.5

55 18 0.011 62.5 62.5

57 17 0.008 62.7 62.5

59 16 0.008 62.5 62.5

61 16 0.009 62.6 62.5

63 15 0.009 77.9 75

65 15 0.009 78.2 78.3

67 14 0.009 78 77.9

69 14 0.009 78.1 78.3

71 14 0.011 78.1 77.9

73 13 0.009 78.5 78.1

75 13 0.009 77.9 78.3

77 12 0.009 78.2 78.2

79 12 0.009 93.4 92.2

81 12 0.01 93.7 93.7

I'm, Lovin' IT, X

Link to post
Share on other sites

I've got it!! :) Woops, I don't!!! :evil:

Well, I thought I had it....Just use AutoITX3.Control as an object called from AutoIT, and I would have access to AutoITX3's Sleep function.

It only worked for times less than 10 msec.

The following code does indeed sleep for about 1 msec (albeit with Task Manager reporting near 100% cpu useage) just like it does when called from Excel. It does this for 1 through 9 msec parameter values.

Dim $oAIX, $Dummy
$oAIX = ObjCreate ("AutoItX3.Control")
$Dummy = $oaix.Sleep (1)
However, AutoITX3 sleep(10) call from Excel sleeps for 10.8 msec, called from within AutoIT, does "exactly" the same thing as AutoIT's sleep function (sleeps sort of multiples of 15 msec). This is strange indeed, but I checked everthing many times to make sure I was doing the tests right. I can send the code to anyone interested.

SO, new request for advice: is there a way to access AutoITX3 sleep function from AutoIT and make it act the same as when called from Excel VBA?

Best Regards

I'm, Lovin' IT, X

Link to post
Share on other sites

from the "for what it is worth department" - more sleep numbers to look at:

http://www.autoitscript.com/forum/index.ph...959entry90959

later....

<{POST_SNAPBACK}>

Thanks for the link. Strange, the reported times there are multiples of 10 msec for small T, I always seem to get multiples of 15. I posted there about this.

Regards, Larry

PS comments there on finding the right search criteria are right...my original search did not find that thread, and it started 3 days prior to this one.

I'm, Lovin' IT, X

Link to post
Share on other sites
  • Administrators

I've got it!! :)   Woops, I don't!!! :evil:

Well, I thought I had it....Just use AutoITX3.Control as an object called from AutoIT, and I would have access to AutoITX3's Sleep function.

It only worked for times less than 10 msec.

The following code does indeed sleep for about 1 msec (albeit with Task Manager reporting near 100% cpu useage) just like it does when called from Excel.  It does this for 1 through 9 msec parameter values.

Dim $oAIX, $Dummy
$oAIX = ObjCreate ("AutoItX3.Control")
$Dummy = $oaix.Sleep (1)
However, AutoITX3 sleep(10) call from Excel sleeps for 10.8 msec, called from within AutoIT, does "exactly" the same thing as AutoIT's sleep function (sleeps sort of multiples of 15 msec).  This is strange indeed, but I checked everthing many times to make sure I was doing the tests right.  I can send the code to anyone interested.

SO, new request for advice:  is there a way to access AutoITX3 sleep function from AutoIT and make it act the same as when called from Excel VBA?

Best Regards

The AutoItX version of Sleep uses the same "Sleep" code as that of SendKeyDelay, WinWaitDelay etc which works like this:

if timetosleep < 15ms then
  Sleep(timetosleep)
else
  start = getCPUtimevalue
  current = start
  while (current-start) < timetosleep
    WINAPI Sleep(0)
    current - getCPUtimervalue
  wend
end if

Sleep(0) is special - it just gives up control of the thread if some other app is waiting otherwise carry on - but the above loop will give the impression of 100% cpu usage. This is not the case however, i've run a game with no loss in fps while testing this :D

Link to post
Share on other sites

The AutoItX version of Sleep uses the same "Sleep" code as that of SendKeyDelay, WinWaitDelay etc which works like this:

if timetosleep < 15ms then
  Sleep(timetosleep)
else
  start = getCPUtimevalue
  current = start
  while (current-start) < timetosleep
    WINAPI Sleep(0)
    current - getCPUtimervalue
  wend
end if

Sleep(0) is special - it just gives up control of the thread if some other app is waiting otherwise carry on - but the above loop will give the impression of 100% cpu usage.  This is not the case however, i've run a game with no loss in fps while testing this :)

<{POST_SNAPBACK}>

Thanks, Jon. Ya, I thought it was something like this, but is the inequality in the first line reversed? Also, is the WINAPI sleep the same as a kernel32 sleep? (my testing of kernel32 sleep gives "identical" timing as AutoIT sleep) My testing suggests that AutoITX form is more like:
if timetosleep > 10 ms then
  Sleep(timetosleep)
else
  start = getCPUtimevalue
  current = start
  while (current-start) < timetosleep
    WINAPI Sleep(0)
    current = getCPUtimervalue
  wend
end if
Besides the change to 10msec, > to <, when I call it from Excel2003 VBA it seems to give quite accurate/reproducible sleep times (about equal to timetosleep+.6 (+/-.1) for timetosleep>9. This suggests to me that the X version does not use exactly the same algorithm as the script version for sleeps>9. Is it possible for AutoIT to use kernel32 sleep and AutoITX use WINAPI (if indeed these are different).

Your posting also confirms an earlier request for info that SendKeyDelay uses such a loop for small delays (I was hoping to do an ugly work around by sending dummy key strokes to get short sleep times, but the cpu useage showed up)

AutoIT doesn't have the if/else, right, it just has the sleep(timetosleep)?

Also re cpu useage, ya I understand that it is not really 100%, it is just as much cpu time as is available. Doesn't this mean that the actual "sleep" time for short sleeps will change depending on how long it takes to complete any other thread, right? This may not be an issue if HT is turned on, but I have HT turned off since if I don't, my Excel will max out at about 60% cpu useage, and it needs to go to about 80% to run my vba without any slow down due to parallel processes. I use VBA "DO EVENTS" to let my parallel scripts get cpu time, "but only when I can afford to let them". With HT turned off, I would imagine apps tend to "fight" over cpu time than when on. By the way, HT off or on makes no difference to my timing test results.

Regards

Larry

I'm, Lovin' IT, X

Link to post
Share on other sites

I think I came up with a function that gives good accuracy, low cpu time, all sleep times.

I posted it in scripts and scraps as "Here's an alternet to Sleep"

Regards (edit, here's a link: Here)

Larry

Edited by lgodfrey

I'm, Lovin' IT, X

Link to post
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
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...