Jump to content

WinWaitDelay and Sleep help


Recommended Posts

I need to get low sleep times (less than 10 msec), with low CPU useage.

I have run a bunch of tests, and would like my conclusions confirmed. Are these right?

1.) Sleep(T) for T<10 sleeps for nominal 10 msec, not T.

2.) winwaitdelay is not used by winexists

3.) winwaitdelay accuracy is similar to sleep accuracy

3.) sendkeydelay (default is 5 msec) internal timing uses an algorithm different than sleep to get timing accuracy for periods less than 10 msec, but that algorithm uses close to 100% cpu time.

If these conclusions are correct, I can see no way to have delays less than 10 msec with an accuracy of at least +/- 1 msec and low cpu useage. :)

Can anyone suggest a method to have an equivalent to sleep(T) for T less than 10 msec, accuracy at least +/- 1 msce, low cpu useage?

Thanks a lot

Larry

edit add:

PS, I just ran sleep from VBA in excel, and it looks like sleep(T) for T<10 actualy works for T<10, but at 100% CPU useage. Actual delay for my system is about T+ 0.1msec for T<10. For T>9, delay is not as accurate, about T+.5 to .7msec., but CPU useage drops to close to zero. So AutoItX sleep method may not be identical to AutoIt sleep method.

Edited by lgodfrey

I'm, Lovin' IT, X

Link to comment
Share on other sites

Will someone help me out here? I am trying to code workarounds on issues with InetGet and Sleep, and I need to make sure my understandings are correct. This info is not in the help files, and I could not find it on the forum. It would appear also that this information is important for an in-depth understanding of these functions/parameter.

Regards

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

Will someone help me out here?  I am trying to code workarounds on issues with InetGet and Sleep, and I need to make sure my understandings are correct.  This info is not in the help files, and I could not find it on the forum.  It would appear also that this information is important for an in-depth understanding of these functions/parameter.

Regards

Larry

<{POST_SNAPBACK}>

not really sure on what kind of help you need...personally i haven't had measure the wait time in milliseconds, and very rarely will i use a sleep for less than 10 milliseconds. what are you using to measure the amount of actual sleep time, and how can you be positive that THAT measurement is exact to the millisecond? what issues exactly are you trying to create workarounds for with inetget and sleep? i ask because it may be easier and quite possibly more helpful to you, to offer help with those issues than the measuring of sleep times..
Link to comment
Share on other sites

I'm afraid I can't help you understand the inner workings of AutoIt but I can offer a solution to what you might be trying to do.

Since you are using such a small Sleep() time, it seems that you are wanting to do some sort of action every certain amount of milliseconds. Perhaps TimerInit() and TimerDiff() would be better suited for this:

local $time = timerInit()
action()
while (timerDiff($time) < 10)
wEnd
; the next action() will execute very close to 10ms after the last action()
action()
while (timerDiff($time) < 10 + 20)
wEnd
; the next action() will execute very close to 20ms after the last action()
action()
while (timerDiff($time) < 10 + 20 + 10)
wEnd
; the next action() will execute very close to 10ms after the last action()
action()
Edited by LxP
Link to comment
Share on other sites

not really sure on what kind of help you need...personally i haven't had measure the wait time in milliseconds, and very rarely will i use a sleep for less than 10 milliseconds.  what are you using to measure the amount of actual sleep time, and how can you be positive that THAT measurement is exact to the millisecond?  what issues exactly are you trying to create workarounds for with inetget and sleep? i ask because it may be easier and quite possibly more helpful to you, to offer help with those issues than the measuring of sleep times..

<{POST_SNAPBACK}>

thanks for the feedback!

I am using timerinit and timerdiff for timing measurements. These functions have accuracies very much better than a millisecond. I think AutoIt uses the high performance timers built into the cpu for these functions, in which case each "tick" is less than a billionth of a second for recent cpus.

Re inetget, in background mode, it does not release control back to the script until after the first host reply is recieved, so it is not true asynchronoous mode. Valik just confirmed this for me. I need true asynchronous mode. I will have to resort to using the WinHTTP object, but that has its own problems, especially error trapping

Re sleep, it does not work well with small sleep times. and it looks like AutoItX sleep behaves different than AutoIt sleep. In my work, every msec counts, so I need something to work well for small sleep times. You mentioned that you use (seldom, yes, but you use it) sleep with times less than 10 msec. Beware, sleep does not work as expected for such small times. I think it usually sleeps for a minimum of about 10 msec. I use sleep extensively since I have multiple executables running at the same time, and I need them each to use as little cpu time as possible while they are waiting for the event to trigger their next action. Speed is critical for me, so I routinely use sub 10 msec timing. So the problem is a generic one for me.

Thanks again,

Larry

Thanks again

larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

Since you are using such a small Sleep() time, it seems that you are wanting to do some sort of action every certain amount of milliseconds. Perhaps TimerInit() and TimerDiff() would be better suited for this:

<{POST_SNAPBACK}>

Thanks for the feedback! Your idea works, but CPU useage is high since code is being executed until the correct amount of time has passed. I need a real sleep function. In my case, the action that you refer to is ussually the code waiting for a trigger event, and the code has to operate "real time", so I need to check for the trigger event every few msec with low CPU useage between checks.

Best Regards

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

Thanks for the feedback! Your idea works, but CPU useage is high since code is being executed until the correct amount of time has passed. I need a real sleep function.    In my case, the action that you refer to is ussually the code waiting for a trigger event, and the code  has to operate "real time", so I need to check for the trigger event every few msec with low CPU useage between checks.

Best Regards

Larry

<{POST_SNAPBACK}>

i could be wrong but it sounds like you may have to go outside of autoit for the solution you're looking for, but it seems to me that any time you have a check being performed every few milliseconds, you're going to end up with high processor time, especially with multiple executables running. have you done anything with java before? the multi-threading possible in java may be good for you. GUI's are a little more involved in java, well actually kind of everything in java is more involved. the only other thing i can think of is for you to post some of your code here, so the people with better knowledge about autoit than me can help you optimize it.
Link to comment
Share on other sites

i could be wrong but it sounds like you may have to go outside of autoit for the solution you're looking for, but it seems to me that any time you have a check being performed every few milliseconds, you're going to end up with high processor time, especially with multiple executables running.

<{POST_SNAPBACK}>

Thanks for the comments. Re processor useage, processors work in the 100's of picosecond range per clock cycle now, so I think it should be possible to run sleep funcitons in msec range with less than 1% cpu useage. To illustrate this, if you run these three lines, "while 1, Sleep(15), wend" , the cpu useage doesn't even register in task manager. So it should be possible to do a Sleep(1) with less than 15% cpu useage (15 times a number less than 1 is less than 15), and I suspect it too would not even register in task manager with any cpu useage, if done right.

I do not know even where to begin with Java, so I will have to wait for AutoIt to have a sleep function good in the msec range, or wait for more help than experts might be willing to give.

Regards

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

Thanks for the comments.  Re processor useage, processors work in the 100's of picosecond range per clock cycle now, so I think it should be possible to run sleep funcitons in msec range with less than 1% cpu useage.  To illustrate this, if you run these three lines, "while 1, Sleep(15), wend" , the cpu useage doesn't even register in task manager.  So it should be possible to do a Sleep(1) with less than 15% cpu useage (15 times a number less than 1 is less than 15), and I suspect it too would not even register in task manager with any cpu useage, if done right.

I do not know even where to begin with Java, so I will have to wait for AutoIt to have a sleep function good in the msec range, or wait for more help than experts might be willing to give.

Regards

Larry

<{POST_SNAPBACK}>

i also really suggest you post some of the code that you're trying to optimize, there are plenty of people active in this forum with more autoit experience than myself, that may be able to help you optimize... it may be a different area of your code that is wasting processor time...can't guarantee that it would help, but the only way to guarantee that it won't is to not do it...
Link to comment
Share on other sites

i also really suggest you post some of the code that you're trying to optimize

<{POST_SNAPBACK}>

the code is pretty trivial, but here it is
Func MyInetGetAsynchronous($URL, $DLfile)
    ;send download request.  will not return control until the first response back from the URL (not truely asynchronous)  you have no control over the amount of time  until the control is returned.  This usually takes less than 100 msec to return control, but can take several seconds (that's why I want to have a truely asynchronous mode).  A fast return here does not mean that the rest of the download will complete quickly.
    InetGet($URL, $DLfile, 1, 1) 

;monitor download status.  If download is taking too long, restart it, otherwise it might take several seconds before it is complete.
    While @InetGetActive
        $TGet0 = TimerInit()
        While TimerDiff($TGet0) < 150 ;98% of the downloads compete within 100 msec after control is returned by InetGet  for the URL I am interested in. If they do not complete quickly, they usually take several seconds to complete.
            Sleep(5);sleeps absolute minimum time AutoIT will allow, about 11 msec
            If not (@InetGetActive) Then Return ;download is complete within the allowed time, so return
        WEnd
        InetGet("abort");download taking too long, so abort and restart
        While @InetGetActive ;make sure the download is aborted prior to starting a new one.
            Sleep(5)
        WEnd
        InetGet($URL, $DLfile, 1, 1);restart the download if the download did not complete withing the alloted time.
    WEnd ;this is possibly an infinite loop, but so is InetGet in syncronous mode (up to your systems default download timeout)
    Return
EndFunc  ;==>MyInetGetAsynchronous

This posting here is about the sleep function...it really sleeps for about multiples of 11 msec for small T eg sleep(1) sleeps 11, sleep(10) sleeps 11, sleep(12) sleeps 22. My code needs to run fast, it hurts to have to wait about 11 msec in the sleep lines, this is about 10% of a typical download time for my URL. I also repeat this thousands of times, so it adds up. I need something that if you say sleep(5), it really sleeps 5.

I've run some tests on the sleep method availble through AutoITX. This sleep funtion appears to work well (accurate to within +1, -0 msec for all T, even T=1) I will start a new post about this in Idea Lab.

If you have any suggestions about AutoIT sleep replacement, or if you spot something in my code, that would be great.

Regards

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

What must not be forgotten is that AutoIt is an interpreted script language, so every time a command must be executed it must be read, parsed and converted to machine code first. Even a 'compiled' AutoIt script operates on the same principle.

I know nothing about AutoIt's development so I can't say whether the Sleep() command can be improved, but if a programmed solution that requires such speed is absolutely necessary then your best option would be to consider a language such as C.

I haven't brought much good news to this thread, have I? :) Sorry about that.

Link to comment
Share on other sites

  • Administrators

The AutoIt Sleep function is non-blocking so that long sleeps don't stop autoit processing other messages (tray icon clicks etc).

I could modify Sleep to block and be more accurate at the <100ms range I suppose.

Link to comment
Share on other sites

The AutoIt Sleep function is non-blocking so that long sleeps don't stop autoit processing other messages (tray icon clicks etc).

I could modify Sleep to block and be more accurate at the <100ms range I suppose.

<{POST_SNAPBACK}>

Couldn't you add an AutoIt option or parameter for Sleep()?

So that we could choose between Sleep & block and Sleep & not block.

Link to comment
Share on other sites

Is using DllCall() to call the Windows API Sleep() applicable to your requirements?

<{POST_SNAPBACK}>

I suspect that this will use the high level timer , not the high accuracy timing capability of the CPU, but I will try to find info on it. Do you have a link to the info?. I do not know anything about DLL's or DLL calls.

Thanks!

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

I know nothing about AutoIt's development so I can't say whether the Sleep() command can be improved, but if a programmed solution that requires such speed is absolutely necessary then your best option would be to consider a language such as C.

<{POST_SNAPBACK}>

With today's processors, you can get away with operating higher level languages like script and still get good execution speed. Of course speed is relative, I am working in the few 100 msec range, put I understand that if I had to go to low msec I would have to do C or something. But the problem is not the overal execution time of the code, it is in wait loops. Whatever language I use has to have low msec wait capability, with low cpu useage, regardless of how long the rest of the execution takes.

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

Couldn't you add an AutoIt option or parameter for Sleep()?

So that we could choose between Sleep & block and Sleep & not block.

<{POST_SNAPBACK}>

I am in favor of this option. Does AutoITX sleep method block, or is this not relavent?

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

  • Administrators

I suspect that this will use the high level timer , not the high accuracy timing capability of the CPU, but I will try to find info on it.  Do you have a link to the info?.  I do not know anything about DLL's or DLL calls.

Thanks!

Larry

The Windows API Sleep function is only accurate to 10/15ms on NT and 55ms on 9x.
Link to comment
Share on other sites

Is using DllCall() to call the Windows API Sleep() applicable to your requirements?

<{POST_SNAPBACK}>

I am trying this, new to DLL calls, here's the test code, but getting @error-1:
;trying to sleep half a second, ten times
Dim $dll, $K, $Sleep
$dll = DllOpen("kernel32.dll")
$Sleep = 500
For $K = 1 To 10
    DllCall($dll, "none", "sleep", "long", $Sleep) 
    ToolTip($K & "   " & @error)
Next
DllClose($dll)
Sleep(5000);to let you see tooltip if dllcall failse
tooltip("")
Exit
returns @error of 1.

What am I doing wrong? Here's MS's info on sleep to augment your link.MS Sleep Info

The dllopen line ruturns $dll=0, which I guess is ok (its not -1)

Best regards

Larry

I'm, Lovin' IT, X

Link to comment
Share on other sites

  • Administrators

I am trying this, new to DLL calls, here's the test code, but getting @error-1:

;trying to sleep half a second, ten times
Dim $dll, $K, $Sleep
$dll = DllOpen("kernel32.dll")
$Sleep = 500
For $K = 1 To 10
;trying to sleep half a second, ten times
Dim $dll, $K, $Sleep
$dll = DllOpen("kernel32.dll")
$Sleep = 500
For $K = 1 To 10
    DllCall($dll, "none", "sleep", "long", $Sleep) 
    ToolTip($K & "   " & @error)
Next
DllClose($dll)
Sleep(5000);to let you see tooltip if dllcall failse
tooltip("")
Exit
    ToolTip($K & "   " & @error)
Next
DllClose($dll)
Sleep(5000);to let you see tooltip if dllcall failse
tooltip("")
Exit
returns @error of 1.

What am I doing wrong?    Here's MS's info on sleep to augment your link.MS Sleep Info

The dllopen line ruturns $dll=0, which I guess is ok (its not -1)

Best regards

Larry

API Names are case sensitive so:

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

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...