The importance of priority

As part of my PhD research, I have to link together a lot of separate components, many of which are running on separate machines, as they’re too much for a single one. You’d think that this was relatively simple, given that a good non-blocking synchronous socket module is part of the standard Python library. Not so! Everything always runs too slowly, even when it’s the only thing running on the machine.

The first time I came across this problem, I was running the vision module and the speech module on the same machine, which communicated with the graphics module on a different one. The speech module just wouldn’t run nicely at all.

Sleep()ing

An obvious solution was to get the various processes to call time.sleep() every so often, so that the other processes would have a chance to do their work. This really didn’t work at all!

Shutting off background processes

My main machine runs a lot of stuff in the background, from my CVS server, to a VNC server, to iTunes. I wondered if some of this was causing the problem, so I shut everything that wasn’t essential down. To my surprise, this made things worse!

The solution

Finally, I clicked on the solution – setting the thread/process priority. By setting the vision module to have a ‘below normal’ thread priority, the speech module worked happily.

Part Two

Many months later, though, I ended up with the same problem – the speech module just wouldn’t work fast enough. Things were a little different, though – the speech module was the only one running on the machine, and synthesis worked ok (last time it stuttered), but the recognition was way slow. The speech module is a complex beast, because it doesn’t actually do the speech stuff itself, but uses COM to get the Microsoft Speech kit to do it.

Once again, I played around with time.sleep()ing, wondering if the network traffic was what was slowing it down (because without the network traffic, it worked nicely), and lots of other things. I even tried increasing the priority of the speech process, and that just made things worse.

Finally, though, I clicked to the actual problem – the speech process wasn’t the one that was doing the speech work, some other process was (accessed via COM), and that one wasn’t getting enough time. The network traffic probably made things worse because it mean that more time was allocated to the speech module process, which is the opposite of what needed to happen.

So I again dropped the priority – this time of the speech module, and lo-and-behold it worked like a charm.

The lesson? Be very careful to set the priorities carefully, and don’t always assume that you want a higher priority for your process. Remember that Windows will do a reasonable job of giving everyone enough time if the priorities are set right.

Note that to set the process priority, the win32process.SetPriorityClass function is used, with the first parameter equal to the result of win32api.GetCurrentProcess(), but the constants needed for the second parameter are missing, even though the win32 help says they are there (I’ll submit this as a pywin32 bug). The ‘below normal’ constant is 16384. [Later: this is fixed in recent versions of pywin32]

technorati tags: ,

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: