Bounded Workloads

Pace yourself - do less work, run slower, and have happy users!

When we have some complex piece of software with multiple subsystems or components, we'll sometimes find that we can't just let them all run as hard as they can. For example, we may want to keep the CPU usage very light on a device so it can regularly enter low power mode.

For today's post, I'm going to use a game loop as an example. Feel free to apply to your own problem domain. We'll assume we have a couple of subsystems - input management, physics computation, rendering, as well as a subsystem coordinator that calls all of these from within the game loop.

If you don't know what a game loop is, Wikipedia has you covered.

Basic Strategies

There are many ways in which you might want to put bounds on how much work you're going to accomplish. Here are some basic strategies to consider.

In many of the strategies above, you might need a way to prioritize what work gets down. I won't get too much into that, as it tends to be quite domain specific. The last item is a special case, where all the work that is considered high priority gets done as soon as possible.

Compound Strategies

If you have multiple kinds of things you want to do, there are also multiple ways to combine the above.

Taking a Nap

How do we avoid doing work? That may seem obvious, but there are multiple ways of going about it, and tradeoffs to consider betwen them.

As a general comment, Sleep is a terrible API for controlling who gets to run. I've only ever used this for high-performance code where I have no synchronization and I might be waiting for a concurrent memcpy and atomic to finish for example - a kind of spinlock helper so to speak.

Another interesting comment is that whenever you delay work, whether it be through a continuation or timer, you'll often find that properly reporting errors in these code paths is tricky (for example, failure to allocate a timer). The Windows threapool APIs are quite good at this, in that they let you allocate everything up front, and then guarantee no allocation failures during execution.

Enjoy your little-at-a-time work!

Tags:  designperf

Home