As you begin a new project, there's an opportunity to plan the details of the work. This means sequencing the specific tasks that need to get done to achieve all the Key Results metrics and eventually deliver the overall Objective. It turns out that there are some more efficient models for scheduling work based on what’s most important. First you need to decide whether it’s better to get more things done in a smaller amount of time or to have things wait the least amount of total time to get completed (Brian Christian and Tom Griffiths: Algorithms to Live By (Henry Holt and Co., 2016) 107).
Let’s assume you work in a kitchen baking cakes. You as an individual person can do several different tasks, each one at a time. You can measure and prep ingredients, operate a mixer, or pour cakes into pans. Let’s also say that you work in a large kitchen and can do any of these things depending on what the rest of the team needs. That means sometimes you’ll be asked to measure ingredients, and at other times you’ll be given ingredients by someone else to run through a mixer, or you’ll get batter to put into pans.
If you have four people come up with different things for you to do and provide the right input for the task they are requesting, what order do you do them in? From your perspective, if you can do only one thing at a time, any order will do because the time required for each task will add together to be the same amount of time regardless which is done first or last or in between. It does, however, matter to the people who are looking for you to do things.
One way to handle this is to take things in the order they were presented. Even though each task can take a different amount of time, you just do them in the order presented and any task which is short on its own will have to wait behind longer tasks that arrived sooner. This can result in more people having to wait more often, but it simplifies the sequencing.
The table below represents tasks in number of time units required to complete each. The second row shows how many tasks are pending to complete, and this represents a worst-case where the fastest tasks arrived last and are getting done at the end.
Another option is to take tasks in the order they can completed most quickly. In this case you would take the shortest task, such as pouring cakes into pans, through to the longest task, measuring and prepping ingredients. This minimizes the number of work items and people who have to wait. Comparing this with the table above, the total time required to complete all 4 tasks is 7. But you reduce the number of tasks waiting to complete to three in one time unit. This is in contrast to taking three time units to get from four to three tasks waiting in the previous example. Likewise, after 4 time units in the first example, we still had 3 tasks pending completion. In this “least waiting” example there is just one.
A third way to prioritize the work is to allow the requestor to tell you when they need it. You could then work the list of tasks by the earliest time due in order to satisfy the greatest number of people / tasks.
In the late 1800s, a worker at the Midvale Steel Works observed that the people and equipment were not being used efficiently (Christian and Griffiths: 106). His name was Fredrick Taylor and he convinced the company to create a planning office. In it, he posted a single bulletin board that laid out all the machines, the tasks they were doing, and what other tasks or machines were waiting on a task to complete. This practice was built on by Taylor’s coworker, Henry Gantt in the 1910s. The charts he developed, now called Gantt Charts, became the de-facto standard for managing large projects even to today.
Although these charts could show dependencies between systems and relative timelines, they did not explain how to find the best sequence for running the machines. Then in 1954, a RAND corporation mathematician named Selmer Johnson published a paper outlining an algorithm that would allow for an optimal schedule for running two related machines. The concepts apply to any two-step process such as running the washer and dryer in your home.
Some loads will take longer to wash but proportionately shorter times to dry. Others, like towels, may take a normal time to wash but a longer time to dry. The best way to plan washing then is to start with the shortest wash that takes the longest to dry. As the washer completes loads, the dryer may still be running. To minimize the overall time spent doing laundry, the longest drying cycle should be chosen from the available loads that have been washed. This same idea can be used on other two-step processes to get them done in the shortest possible time.
A Danger to Scheduling: Priority Inversion
The worst issue that can happen to a person or machine capable of performing multiple different tasks is having a lower priority task preventing a high priority task from completing. The issue is called priority inversion and it happened on NASA’s 1997 Mars Pathfinder mission (Christian and Griffiths: 112-113). It had a high priority task that wasn’t getting done because a lower priority task had locked a system resource but was unable to finish before it had to move on to another activity. Since the high priority task needed the same resource, it could not run. Each time the low-priority task ran, it never had time to complete and kept the key resource occupied, even when it was not running. This resulted in middle-priority tasks running until an inactivity timer expired for the highest-priority item and resulted in a system reboot. This cost the team the better part of a day. One to two days later, it happened again.
After NASA was able to reproduce the problem, they fixed it with a process called priority inheritance. This means that if a low-priority task is preventing a higher priority one from executing, the first task temporarily takes on the higher priority of the second task so it can move out of the way.
There are three ways to prioritize work for a machine capable of multiple tasks
Perform tasks in the order presented
Perform tasks in order of least time required to complete
Allow the requestors to set a time due, the prioritize any conflicts using the first two methods
When running a system of two inter-related functions, the fastest way to get the work completed is to pick the shortest task that the first function can complete that takes the longest for the second function to complete. Continue this process until the all the tasks are done.
Dependencies between multiple functions or machines can be mapped using Gantt charts
Beware priority inversion, where a low-priority task ties up resources needed by a high-priority task which keeps the high-priority task from running. The solution is priority inheritance, where the lower-priority task takes on the priority of the dependent higher-priority task temporarily so it can release the shared resource.