Jump to content

CPU load with GuiGetMsg type of loop


Uten
 Share

Recommended Posts

First of all I would like to thank the devs for slashing CPU usage in the latest release of AutoIt when using the traditional While 1 ... GuiGetMsg() ... Sleep(100) ... Wend code.

Then my question:

If I use the WaitMessage api call it will be reduced further:

dllcall("user32.dll","int","WaitMessage")oÝ÷ Ø*.Öj+LzÆ yÆ¥X¤zØb²«Ø^{^®v¥Âäx,¡ð.¶­I©©ç(u殶­sb5&Vvöâ6ö×ÆW"F&V7FfW26V7Föà¢66ö×ÆW%ö6ö×&W76öâÒ@¢66ö×ÆW%ô÷WDfÆUõGSÖWP¢66ö×ÆW%÷'VåögFW#ÖÖ÷fRõgV÷C²V÷WBRgV÷C²gV÷C²UDTÕRgV÷C°µWBB6ö×vW&RâDvW&R÷W"7W÷6VBFòfR66W70¢66ö×ÆW%÷'VåögFW#ÒgV÷C²UDTÕRb3#²W67&FfÆRRæWRgV÷C°¢6VæG&Vvöà ¢b33c¶tÖRÒuT7&VFRgV÷CµvFærf÷"ÖW76vW2gV÷C²ÂCÂ3¢b33c¶t'FãÒuT7G&Ä7&VFT'WGFöâgV÷C¶'FãgV÷C²ÂÂ#sÂCÂ#R¢b33c¶tÆ7BÒuT7G&Ä7&VFTÆ7BgV÷C²gV÷C²ÂRÂRÂ3Â#cR¤uT6WE7FFR¤Æö6Âb33c¶×6rÂb33c¶×6u¦W&ô6÷Vç@¥vÆR¢b33c¶×6rÒuTvWD×6r¢bb33c¶×6rÒFVâ b33c¶×6u¦W&ô6÷VçB³Ò FÆÆ6ÆÂgV÷C·W6W#3"æFÆÂgV÷C²ÂgV÷C¶çBgV÷C²ÂgV÷CµvDÖW76vRgV÷C²µG'Fò6öÖÖVçBB÷WBæBfVVÂFRFffW&Væ6P¢VÇ6Tbb33c¶×6rÒb33c¶t'FãFVâ wV7G&Å6WDFFb33c¶tÆ7BÂõU"fײb33³¢b33²fײÔâfײb33³¢b33²fײ4T2fײb33²b33c¶×6u¦W&ô6÷VçC£Òb33²fײb33c¶×6u¦W&ô6÷VçBfײb33·Âb33²¢VÇ6Tbb33c¶×6rÒÓ2FVâ WDÆö÷¢VæDb¥tVæ@¤W@
Link to comment
Share on other sites

Could a WaitMesage call like this harm the internal workings of Autoit?

Possible. That call is a sort of "wait untill <this> happens" -loop (it does not return untill a new event is available in the message-loop). It means that any kind of "event" that does not go thru the (internal) message-loop wil be blocked.

The possible (negative) effects strongly depend on what you've written.

P.s.

Do you know that you can allso work in an event-driven mode (instead of the polling one) by using GUIOnEventMode=1 ?

Link to comment
Share on other sites

Possible. That call is a sort of "wait untill <this> happens" -loop (it does not return untill a new event is available in the message-loop). It means that any kind of "event" that does not go thru the (internal) message-loop wil be blocked.

The possible (negative) effects strongly depend on what you've written.

P.s.

Do you know that you can allso work in an event-driven mode (instead of the polling one) by using GUIOnEventMode=1 ?

Is that right. Perhaps you should try this. Move your mouse around the Gui.

$gMe = GUICreate("Waiting for messages", 400, 300)
$gBtn1 = GUICtrlCreateButton("btn1", 10, 270, 40, 25)
$gList = GUICtrlCreateList("", 5, 5, 390, 265)
GUISetState()
Local $msg, $msgZeroCount
While 1
   $msg = GUIGetMsg()
   If $msg < 0 Then MsgBox(0, '', 'Message', 1)
   If $msg = 0 Then 
      $msgZeroCount += 1
      dllcall("user32.dll","int","WaitMessage") ;Try to comment it out and feel the difference
   ElseIf $msg = $gBtn1 Then 
      GuiCtrlSetData($gList, @HOUR & ':' & @MIN & ':' & @SEC &  '   $msgZeroCount:=' & $msgZeroCount & '|') 
   ElseIf $msg = -3 Then 
      ExitLoop
   EndIf 
WEnd

@Uten

What is the Gui forum used for?

Link to comment
Share on other sites

Is that right. Perhaps you should try this. Move your mouse around the Gui.

I'm sorry, but I seem to be missing something here : what are you trying to prooved/disproove here ?

As for your code, try this :

#include <GUIConstants.au3>
$gMe = GUICreate("Waiting for messages", 400, 300)
$gBtn1 = GUICtrlCreateButton("btn1", 10, 270, 40, 25)
$gList = GUICtrlCreateList("", 5, 5, 390, 265)
GUISetState()
Local $msg, $msgZeroCount,$OldSec=0
$msg = GUIGetMsg()
While $msg<>$GUI_EVENT_CLOSE
    If $msg = 0 Then $msgZeroCount += 1
    if @sec<>$OldSec then   
        $OldSec=@SEC
        GuiCtrlSetData($gList, @HOUR & ':' & @MIN & ':' & @SEC &  '   $msgZeroCount:=' & $msgZeroCount & '|')
        $msgZeroCount=0
    EndIf
    $msg = GUIGetMsg()
    dllcall("user32.dll","int","WaitMessage") ;Try to comment it out and see the difference
WEnd
Granted, unexpected by be me the dll-call does not lock-up the loop until a next usable (non-zero) $msg comes around. But hey, the above loop is not the one the dll-call has effect on. :)
Link to comment
Share on other sites

$gMe = GUICreate("Waiting for messages", 400, 300)
$gBtn1 = GUICtrlCreateButton("btn1", 10, 270, 40, 25)
$gList = GUICtrlCreateList("", 5, 5, 390, 265)
GUISetState()
Local $msg, $msgZeroCount, $count = 0
While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case -3
            ExitLoop
        Case -100 To 0
            ContinueLoop
    EndSwitch
   If $msg < 0 Then
       $count += 1
       GuiCtrlSetData($gList, $count & ' ' & $msg)
   EndIf
   If $msg = 0 Then 
      $msgZeroCount += 1
      dllcall("user32.dll","int","WaitMessage") ;Try to comment it out and feel the difference
   ElseIf $msg = $gBtn1 Then 
      GuiCtrlSetData($gList, @HOUR & ':' & @MIN & ':' & @SEC &  '   $msgZeroCount:=' & $msgZeroCount & '|') 
   ElseIf $msg = -3 Then 
      ExitLoop
   EndIf 
WEnd

If you comment and uncomment the switch block then you will see differences. If commented, then you will see $msgZeroCount increase and will see $count increase with any mouse movement. Thus the block idea mentioned with GuiGetMsg() of non events seems to be inappropriate. 0 and -11 events AFAIK are unwanted messages in this script to cycle the loop. Big loops with lots of conditions would appreciate the Switch block a lot more.

Link to comment
Share on other sites

@BitRot:

Your right WaitMessage will not return before there is a message in the message queue. I started to play around with it before I noticed that you don't need to make sleep calls manually anymore to reduce CPU load.

As there is only one message queue for each thread using a GUI, and AutoIt is a single threaded script language I thought placing it there would ease the load of my CPU quite a lot since the thread is not called again by the OS before it has something to do. I suppose that even will ease off swapping as I'm often using memory constrained machines.

The sample you provided does show that a WaitMessage call will reduce the zerocount to 1/3 of normal call count. By accident I just tried it with AdlibEnable and that timer was not blocked as fare as I could observe.

I'm not trying to prove anything just playing around with some API calls to see if I can improve my code.

I'm aware of the event-driven mode. I guess I'm using the message loop style out of old (bad?) habit.

@MHz: Your right about the GUI forum, sorry about that :">

When I started to play around with this it was in connection with messages not coming from the GUI so in my head was not a GUI question. If any moderator reads this and it is possible to move the thread to the GUI section feel free to do so.

Link to comment
Share on other sites

If you comment and uncomment the switch block then you will see differences. If commented, then you will see $msgZeroCount increase and will see $count increase with any mouse movement. Thus the block idea mentioned with GuiGetMsg() of non events seems to be inappropriate. 0 and -11 events AFAIK are unwanted messages in this script to cycle the loop. Big loops with lots of conditions would appreciate the Switch block a lot more.

Your right if the application at hand is the one your working in but then it does not really matter much as you will be doing other things in it or get information from it. But if you start working in another application then there will be a difference. Admittedly not a big one anymore as the internal workings of AutoIt has taken care of it in the latest release (beta) :)
Link to comment
Share on other sites

If you comment and uncomment the switch block then you will see differences. If commented, then you will see $msgZeroCount increase and will see $count increase with any mouse movement. Thus the block idea mentioned with GuiGetMsg() of non events seems to be inappropriate.

I'm sorry,but I again seem to be missing something here. Is the GUIGetMsg() result-code -11 not an event ? And what has your switch-block that is just skipping the incrementing of the $msgZeroCount-variable has to do with anything (if anything I would call that cheating :P )

0 and -11 events AFAIK are unwanted messages in this script to cycle the loop.

I agree with the value-zero result event. As for that -11 (and others) event that might be, in this case and for you, true. But they are generated & returned events.

I do not know what the author of AutoIt did in the GUI's message-loop, but I get the strong feeling he uses a timer/alarm to generate those value-zero GUIGetMsg() -results. Probably so that the message-loop gets done ever so often, so that other (non event-generating) events/situations can get handled too (for instance : I seem to be missing all sorts of tcp-events, meaning I have to poll for reception :)).

[edit]

@Uten :

I just realized why that "1/3 of normal call count" looked so familiar : 18 ticks a second is near equal to the 18.2 ticks-a-second timer-tick frequency. It could be coincidence though ...

Edited by BitRot
Link to comment
Share on other sites

  • 3 weeks later...

@BitRot: Thanks for your input. Did not catch the last one before now. You seem to miss events when using functionality that does not regard a UI.

I have also found that WaitMessage API calls will cause problems for AutoIt if I Create two or more windows (the second window is not painted).

So all in all only use for simple stuff that lives for the most part in a idle state. I have some applications just hanging around in the tray just staing idle until I need them. For those I have found a decrease in CPU usage.

Anyhow and as mentioned before as of AutoIt-v3.2.1.x it is not a consern anymore :lmao:

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