What is the best way to control the CPU load produced by SikuliX?

Asked by Krum Cheshmedjiev on 2015-02-15

Thanks about great tool!

I am first time with Python and Sikuli... How can I check CPU load for specific processes, to ensure that Sikuli (v1.0.1, Win32 Vista) don't overload them? It must handle a Win program with lot of graphics, so the program delays often, and unpredictable. My idea is to set Sikuli to wait, until load of the CPU by specific processes drops low.

I try to use psutils, but can not load it successfully. I have installed Python long time ago for a tool, so I install psutils there. Here is the code I used in Sikuli IDE:

import sys
importPath = "c:\\Python26\\Lib\\site-packages"
if not importPath in sys.path: sys.path.append(importPath)
import psutil

And here is the error:

[error] script [ SikuliX ] stopped with error in line 16
[error] SyntaxError ( ("mismatched input 'as' expecting COLON", ('c:\\Python26\\Lib\\site-packages\\psutil\\__init__.py', 549, 32, ' except AccessDenied as err:\n')) )

Line 16 in the last one in my code.

I am not tied to this solution, anything else, which allows me to check CPU load by process, will works. Any other ideas?

Question information

Language:
English Edit question
Status:
Solved
For:
Sikuli Edit question
Assignee:
No assignee Edit question
Solved by:
RaiMan
Solved:
2015-02-18
Last query:
2015-02-18
Last reply:
2015-02-16
RaiMan (raimund-hocke) said : #1

The basic concept of SikuliX is to wait on a given image to appear on the screen.
The standard waiting time is 3 seconds, that can be extended either globally, per region or per function.
During this given waiting time SikuliX periodically takes a screenshot (whole screen or given region), to search for the given image in this shot-image.
This is repeated until either the image appeared or the waiting time limit is reached.

The search of the given image in the actual screenshot-image is our number crunching and for some 10 to some 100 milliseconds creates a very high cpu load.
On weak machines and always searching the whole screen (instead of customized restricted smaller region) this may lead to a constantly high cpu load, that might have an impact on other processes demanding much cpu too.
In this case, in a first step one should try to minimize the searches (some click locations might be evaluated as relative to matches already found before) and make the search regions as small as possible.
If this is not enough, than one might lower the scan rate (the rate at which SikuliX agin looks for the given image on the screen) either gnerally or in critical parts of the workflow.

In the standard the scan rate is 3, meaning, that only after 1/3 of a second after the previous search started, a new search is started. As mentioned already: on weak machines, with large screens and always searching the whole screen this may lead to a "always searching" situation with high cpu load. A search on a weak machine on the whole screen on average may take more than 500 millisecs.

So if you think, you have this problem and are using optimized workflows, you might adjust the scan rate:
http://sikulix-2014.readthedocs.org/en/latest/scripting.html#Settings.WaitScanRate

Thanks a lot about detailed explanation.

Unfortunately, I can not benefit from that, because of bad explanation of mine... My question with other words:

How can I check the CPU load of "program1.exe" and "program2.exe" processes, from the inside of Sikuli script?

Means, it's not Sikuli issue, but programing issue, which I try to achieve. Sikuli works great (thanks again!), but other programs delay the computer (but Sikuli handles them), and I must set Sikuli to wait for them. So that's because I try to insert psutils.

Any suggestions?

Best RaiMan (raimund-hocke) said : #3

LOL, already thought that you might be more in this direction.
Nevertheless: sometimes I take the chance with a question to write down some general comments.
Might be it helps others.

BTW: thanks for feedback on SikuliX.

Your problem:
In such system specific cases there are only 3 options:
1. find a Python package, that works with Jython or some Java library
2. access the Windows API with some Java JNI/JNA package (e.g. BridJ, that I use), but usage is rather complex
3. find an appropriate Windows command, that reveals the needed information

In this case option 3 is sufficient:

cmd = "wmic path Win32_PerfFormattedData_PerfProc_Process get Name,PercentProcessorTime"
# yields output like:
# process_name cpu_utilization_value_in_%
# example 30
# example1 12

cmdOut = run(cmd) # issue command
# check the command output
info = cmdOut.split("\n") # get the output as list of lines
for line in info:
    line = line.strip() # get rid of suttounding whitespace
    if line.endswith(" 0"): continue # skip entries having value 0
    print line
    (name, cpu) = line.split() # get the name and percentage
    # and more processing as you like

You might put this into a function.

Thanks again, this is what I need.

When it works, it's great! Unfortunately, sometimes CPU load check works deadly slow, so it is possible to miss it with frozen program... And I can not find why...

So I set Sikuli just to wait for few seconds at conflict points, and everything works. Still will be overloads, but rare.

Thanks anyway :-)

Thanks RaiMan, that solved my question.