ShawnW Posted July 12, 2010 Posted July 12, 2010 Often when I look over others scripts while trying to help people on the forums, I see something like While True Sleep(1000) ; This is so the cpu usage doesn't go nuts. WEnd Valid point because I too noticed a while back that it hits 40% cpu usage if I don't slow down the loop at all. But I also know that even lower end modern processors process about 15-150 billion Instructions per second. Now I know many many instructions are used for each operation from a high level language standpoint but that is still a lot. It would seem to me that you could get just as good of results by only sleeping for 1 millisecond as you could for 1 second, because a millisecond from a processor standpoint allows a ton of instructions through. Basically it would be better to use this because it would not kill the cpu and still not slow down the rest of your program by any noticeable amount. While True Sleep(1) ; This is so the cpu usage doesn't go nuts. WEnd Seems to work in simple testing for me. Can anyone disprove it? -Shawn
MvGulik Posted July 12, 2010 Posted July 12, 2010 Seems to work in simple testing for me. Can anyone disprove it?Probably not.PS: The sleep command uses a general step value of about 10..12. So the effect of a sleep(1) or sleep(10) are effectively the same. "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ...
Tvern Posted July 12, 2010 Posted July 12, 2010 A loop like that should only be used when waiting for an event message (correct me if I'm wrong). Event messages are processed in the middle of the sleep rather than waiting till the sleep ends. This displays it nicely: Opt("GUIOnEventMode",1) HotKeySet("e","_HotKey") ;(press e) GUICreate("OnEvent Test") GUISetOnEvent(-3,"_GUISetOnEvent") ;(close GUI) GUICtrlCreateButton("Event!",10,10) GUICtrlSetOnEvent(-1,"_GUICtrlSetOnEvent") ;(press button) GUISetState() GUIRegisterMsg("0x0047","_GUIRegisterMsg") ;(Move GUI) While 1 Sleep(24*60*60*1000) ;sleep one day to REALY reduce cpu usage ConsoleWrite("Sleep complete!" & @CRLF) ;this should not print unless you leave it running. WEnd Func _HotKey() MsgBox(0,"Event!","E was pressed!") EndFunc Func _GUISetOnEvent() MsgBox(0,"Event!","The GUI is closed!") Exit EndFunc Func _GUICtrlSetOnEvent() MsgBox(0,"Event!","Event button was pressed!") EndFunc Func _GUIRegisterMsg() MsgBox(0,"Event!","The GUI was moved!") EndFunc GuiGetMsg automatically idles the cpu, so it should not be combined with a sleep(). If a loop has a way to exit, or if a loop contains function calls the sleep should be appropriately short so that the user doesn't experience a noticable delay as you posted.
MvGulik Posted July 12, 2010 Posted July 12, 2010 (edited) Event messages are processed in the middle of the sleep rather than waiting till the sleep ends.Technically probably incorrect, but events (OnEvent, Hotkeys, Adlib, etc) don't wait for anything. They spawn a new code processing line while putting the current code processing line on hold. No matter what command is/was currently being processed (sleep or otherwise.)(ignoring exceptions to the rule.)Ps: Your code only shows(proofs) that in relation to sleep, sleep will no block other event calls. Edited July 12, 2010 by MvGulik "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ...
trancexx Posted July 12, 2010 Posted July 12, 2010 Technically probably incorrect, but events (OnEvent, Hotkeys, Adlib, etc) don't wait for anything. They spawn a new code processing line while putting the current code processing line on hold. No matter what command is/was currently being processed (sleep or otherwise.)(ignoring exceptions to the rule.)Ps: Your code only shows(proofs) that in relation to sleep, sleep will no block other event calls.Would you believe me if I tell you you got it all wrong?You are fooled by the way Sleep() is implemented in AutoIt. While sleep everything sleeps for real. But Sleep() is in reality series of linked sleeps. Functions you mention are executed in the mean time, i.e. they wait all right. ♡♡♡ . eMyvnE
Tvern Posted July 12, 2010 Posted July 12, 2010 I wasn't making assumtions about the way it's implemented. (didn't mean to anyways), but rather tried to best explain the way AutoIt behaves for the end user. For that purpose I think my explanation was correct, or am I missing something here?
MvGulik Posted July 12, 2010 Posted July 12, 2010 I wasn't making assumtions about the way it's implemented. (didn't mean to anyways), but rather tried to best explain the way AutoIt behaves for the end user. I know.Its more or less the same for me btw. "Technically probably incorrect" -> or: mainly from a AutoIt user's code point of view.With Event messages are processed in the middle of the sleep rather than waiting till the sleep ends. I feel your kinda suggesting there is some relation between sleep() and event driven code execution. And from a users code point of view there is no relation. (At least not to me. Might change today ... maybe.) "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ...
MvGulik Posted July 12, 2010 Posted July 12, 2010 Would you believe me if I tell you you got it all wrong?That I'm wrong. Sure.That your right ... Depends on if I'm able to follow any additional supplied argumentation and if it can match it up with there intended contextual point of view.You are fooled by the way Sleep() is implemented in AutoIt.Not really sure I'm following you here.- I have never seen how sleep is implemented in AutoIt itself.- You mean: "... fooled by the virtual way sleep seems to work from a AutoIt users point of view, compared to how sleep actually is implemented in AutoIt itself" ?The "Technically probably incorrect" was my way of saying something similar. That part seems to have backfired.While sleep everything sleeps for real. But Sleep() is in reality series of linked sleeps.That crossed my mind, and made sense. But I did not see the significants of this to the virtual way AutoIt code is executed or behaves.Functions you mention are executed in the mean time, i.e. they wait all right.You lost me here.- Assuming internal AutoIt POV.- What do you mean with "in the mean time".- "They wait all right". wait for what? Internal/real issued sleep commands by AutoIt? (That makes no sens to me. As AutoIt can be considered out-cold when "its" in a true sleeping state. With 'Waiting' I presume some sort of active state.) "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ...
trancexx Posted July 12, 2010 Posted July 12, 2010 (edited) Not really sure I'm following you here.- I have never seen how sleep is implemented in AutoIt itself.- You mean: "... fooled by the virtual way sleep seems to work from a AutoIt users point of view, compared to how sleep actually is implemented in AutoIt itself" ?The "Technically probably incorrect" was my way of saying something similar. That part seems to have backfired.You have wrong assumptions and derived wrong conclusions. All based on wrong premises (if any).That crossed my mind, and made sense. But I did not see the significants of this to the virtual way AutoIt code is executed or behaves.AutoIt is high level language in development phase. Serious work with it requires understanding of the internal workings. Anyone (and I mean anyone) saying different is plain ignorant. You lost me here.- Assuming internal AutoIt POV.- What do you mean with "in the mean time".- "They wait all right". wait for what? Internal/real issued sleep commands by AutoIt? (That makes no sens to me. As AutoIt can be considered out-cold when "its" in a true sleeping state. With 'Waiting' I presume some sort of active state.)When you do Sleep(250) AutoIt will (most likely) split that to 25 calls to Sleep function -the one I linked to. Between those sleeps AutoIt will be active. Proving this is trivial but since the audience isn't of that type, I won't for example.And functions that use other threads (Inet... whatever) shouldn't be affected by any sleep. Edited July 12, 2010 by trancexx ♡♡♡ . eMyvnE
MvGulik Posted July 12, 2010 Posted July 12, 2010 (edited) Right. I'm cutting this "trancexx versus me" short as I don't see this resulting in anything useful.Anyone that thinks he/she (or both) can clear up the confusion. ... (Here or PM if you like). Edited July 13, 2010 by MvGulik "Straight_and_Crooked_Thinking" : A "classic guide to ferreting out untruths, half-truths, and other distortions of facts in political and social discussions.""The Secrets of Quantum Physics" : New and excellent 2 part documentary on Quantum Physics by Jim Al-Khalili. (Dec 2014) "Believing what you know ain't so" ... Knock Knock ...
evilertoaster Posted July 12, 2010 Posted July 12, 2010 (edited) I can't necessarily say how AutoIt currently does it, but we do know how it USED to handle sleeps based on the old source code. First, the function itself: AUT_RESULT AutoIt_Script::F_Sleep(VectorVariant &vParams, Variant &vResult) { // Handle sleep 0 as a special if (vParams[0].nValue() <= 0) ::Sleep(0); else { m_tWinTimerStarted = timeGetTime(); // Using the WinWait timer - go fig. m_nWinWaitTimeout = vParams[0].nValue(); m_nCurrentOperation = AUT_SLEEP; Execute(); } return AUT_OK; } // Sleep() So from here we see that Sleep(0) actually directly invokes the windows API Sleep(). Otherwise it leverages a custom timing mechanic (in fact, the same one used for WinWait) and invokes a separate call to Execute() (which is the line-by-line function handler). Following the Execute() code we see: AUT_RESULT AutoIt_Script::Execute(int nScriptLine) { MSG msg; VectorToken LineTokens; // Vector (array) of tokens for a line of script const char *szScriptLine; ... ... while(m_bWinQuitProcessed == false && m_bUserFuncReturned == false) { // Run the windows message loop and handle quit conditions ProcessMessages(); // If script is in a quit state then don't execute any more code if (m_nCurrentOperation == AUT_QUIT) break; // Exit while loop // If we are waiting for something (winwait, sleep, paused, etc) then loop again if (HandleDelayedFunctions() == true) continue; ... .... } The "HandleDelayedFunctions" function is where it does the actual 'sleeping', the execute loop just calls that until it returns false: HandleDelayedFunctions does what its name implies, and handles the various waiting functions in AutoIt, among them all of the "proccess waits", handled by this function (only the first part is included, since it pertains to the discussion): bool AutoIt_Script::HandleProcessWait(void) { // Any ProcessWait commands to process? if (m_nCurrentOperation != AUT_PROCESSWAIT && m_nCurrentOperation != AUT_PROCESSWAITCLOSE) return false; // Idle a little to remove CPU usage Sleep(AUT_IDLE); // If required, process the timeout if (m_nProcessWaitTimeout != 0) { // Get current time in ms DWORD dwDiff; DWORD dwCur = timeGetTime(); if (dwCur < m_tProcessTimerStarted) dwDiff = (UINT_MAX - m_tProcessTimerStarted) + dwCur; // timer wraps at 2^32 else dwDiff = dwCur - m_tProcessTimerStarted; // Timer elapsed? if (dwDiff >= m_nProcessWaitTimeout) { m_vUserRetVal = 0; // We timed out (default = 1) m_bUserFuncReturned = true; // Request exit from Execute() m_nCurrentOperation = AUT_RUN; // Continue script return true; } } ... ... } So we see that it actually just does a poll to see how much time has elapsed since the timer init (standard wait behavior). Also, it directly invokes this line: // Idle a little to remove CPU usage Sleep(AUT_IDLE); which is a constant of 10. Which tells us that even a Sleep(1) in AutoIt, calls a Sleep(10) to the Windows API already. As to the OP's question: I'd say that circumstantially, you'd either want to do a sleep(0), to give another processes some time share, sleep(1)-sleep(10) if you want to give the minimal "AutoIt aware" sleep value, or something higher, like Sleep(500) if you don't need the script to be instantaneously responsive. Edited July 12, 2010 by evilertoaster
AdmiralAlkex Posted July 13, 2010 Posted July 13, 2010 (edited) If you really want to sleep for 1 ms (or even something much lower), then look at _HighPrecisionSleep() Edited July 13, 2010 by AdmiralAlkex .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
ShawnW Posted July 13, 2010 Author Posted July 13, 2010 (edited) Thanks evilertoaster, I was watching this thread go way off track, your the only one that kind of understood what I was talking about. All I was asking is that if your goal is only to reduce CPU load from an infinite loop with no delays, then is there any real benefit from the commonly used Sleep(1000) or Sleep(500) over Sleep(1)? And furthermore wouldn't Sleep(1) be better since it does less damage to the speed of the program? In my tests, Sleep(0) still causes a cpu load (35-40%), whereas Sleep(1) does not (doesn't even register as a % usage). So I think Sleep(1) might be better if your goal is to have a fast infinite loop, with unnoticeable delay, and no abnormal cpu usage spikes. -Shawn Edited July 13, 2010 by ShawnW
Tvern Posted July 13, 2010 Posted July 13, 2010 I think Sleep(1) might be better if your goal is to have a fast infinite loop, with unnoticeable delay, and no abnormal cpu usage spikes.I still don't see the advantage of this over a longer sleep. Seen as looping Sleep(1) will repeatedly sleep for 10ms and Sleep(1000) will... repeatedly sleep for 10ms.In OnEvent mode one should not be more responsive than the other. In messageloop mode there should not be a sleep.The difference should only be notable if the loop also contains other code to be executed, which I don't hear you about.
ShawnW Posted July 13, 2010 Author Posted July 13, 2010 I still don't see the advantage of this over a longer sleep. Seen as looping Sleep(1) will repeatedly sleep for 10ms and Sleep(1000) will... repeatedly sleep for 10ms.In OnEvent mode one should not be more responsive than the other. In messageloop mode there should not be a sleep.The difference should only be notable if the loop also contains other code to be executed, which I don't hear you about.Well not all scripts require user response or events. Say I want a script to loop in the background doing some task, or maybe constantly checking something, or even a series of mouse clicks. The point is there are times when you want quick program looping so you get continuous iterations, where there are no events because all it is doing is running more code over and over. Yet without sleep the cpu usage would skyrocket.-Shawn
AdmiralAlkex Posted July 13, 2010 Posted July 13, 2010 @ShawnWYou seemed to have miss what eviltoaster really said.Which tells us that even a Sleep(1) in AutoIt, calls a Sleep(10) to the Windows API already.So Sleep(1) is completely pointless, and is only going to create confusion. Either use Sleep(10) or _HighPrecisionSleep(), which works down to 100 nano seconds. .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
ShawnW Posted July 13, 2010 Author Posted July 13, 2010 (edited) @ShawnWYou seemed to have miss what eviltoaster really said.So Sleep(1) is completely pointless, and is only going to create confusion. Either use Sleep(10) or _HighPrecisionSleep(), which works down to 100 nano seconds.I appreciate your concern, and _HighPrecisionSleep() certainly seems like a useful function to use in the future, but this is not what I'm trying to do.I wasn't comparing 1 to 10, (although I'm not sure I buy that, not the point and I don't wish to discuss it) I was comparing it to something that might actually make a difference. I'll make the argument Sleep(10) better than Sleep(500) or Sleep(1000) if it makes you happy. The only thing I'm questioning is the minimum amount of delay required to keep the CPU load from going nuts. Edited July 13, 2010 by ShawnW
AdmiralAlkex Posted July 13, 2010 Posted July 13, 2010 (edited) The only thing I'm questioning is the minimum amount of delay required to keep the CPU load from going nuts.Did you see this note by monoceres in the thread I linked too? (post #9)Actually, I just tested and 100 nanoseconds of sleep is enough to keep the CPU percentage at 0% on my machineSo the time you choose is pretty much irrelevant.Edit: But I would think that bigger is better, unless you have a reason to go really low. If nothing else, at least I would expect that to be more energy efficient (laptops are popular nowadays). Edited July 13, 2010 by AdmiralAlkex .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
ShawnW Posted July 13, 2010 Author Posted July 13, 2010 Did you see this note by monoceres in the thread I linked too?Nope, pretty cool. Your right though, I don't need that low but at least the question is answered. Thanks!-Shawn
AdmiralAlkex Posted July 13, 2010 Posted July 13, 2010 (edited) I'm happy I could be of some help (and that you're still listening to me ) Edited July 13, 2010 by AdmiralAlkex .Some of my scripts: ShiftER, Codec-Control, Resolution switcher for HTC ShiftSome of my UDFs: SDL UDF, SetDefaultDllDirectories, Converting GDI+ Bitmap/Image to SDL Surface
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now