Last night I spoke about parallel programming techniques. I’ve given many technical talks. Technical to the point of walking through actual examples. But, technical details are a dime a dozen these days thanks to Google. And they’re easily forgotten, after all there are so many of them. So many I can’t even begin to cover a fraction of the possibilities with a subject like parallel programming in two hours.
When I give talks like these I challenge myself to find something to share that isn’t so easily found on Google. Something that when combined with the in person experience is memorable and actionable for participants. Some way for participants to walk away with the ability to improve. Not just some exposure to technical details that will quickly fade.
Last night, I wanted participants to walk away with a strategy to apply the techniques with a guarantee that the results would improve their organization. I started the presentation with the following approach, and then used it to guide each example.
1. Establish a Goal
Many parallel programming techniques are cool and appear easy to use. It’s tempting to dive in head first and see how fast the system can be. That’s like a doctor prescribing a hip new medication before asking the patient for symptoms. Instead, we need to first establish a GOAL. The goal should contain an objective, a measure of success and why it’s valuable.
An objective might be something as simple as improving the performance of a system to handle an expanding user base. Let’s say we anticipate 20% growth in the next year and we suspect we might need to make some changes to make that happen. So, 20% is the measure of success. Why is it valuable? Well perhaps we should ask how likely the 20% growth is. Maybe put some bounds on it, 10% to 30%. And then talk about the financial impact.
This establishes a basis to make an investment decision about optimizing an existing system. It helps us establish how fast, is fast enough. Systems don’t need to be as fast as possible, they need to be sufficiently fast.
With the goal in mind, we can dive into diagnosing the system. We can leverage many dimensions to determine what our system currently supports. Perhaps the system can already handle the growth. Perhaps it can’t. Here’s a few techniques that can help:
- Use intuition by looking at the system. But, don’t stop there, intuition is just that. Validate it.
- Use monitoring and instrumentation in actual systems to understand how they perform now.
- Use profiling to do advanced analysis of the system to look for bottlenecks.
You should have a few other ideas to add to this list. Diagnosis is an art. What’s important is that we diagnose from the perspective of what we’d like to accomplish. If you go to the doctor because you’re sick, the doctor is going to diagnose in terms of making you feel better. They’re not going to throw in an annual physical while they’re at it. By having a goal in mind, we can constrain our diagnosis.
At some point in the diagnosis we’ll have enough information to make a guess about what we can do to handle the customer growth. Just like a doctor who pokes and prods, eventually they have an aha moment and have something they would like to try.
Perhaps you can apply some techniques from parallel programming to improve the system. But, because we started with a concrete goal rooted in improving the business, we may have other options. Parallel programming becomes one of many tools to improve our business. Perhaps a few optimizations will be sufficient to handle the growth. Perhaps distributed computing is a better idea. Perhaps we notice something completely unexpected.
4. Try it
Of course we want to test our prescription. Just like a patient follows doctors orders, hopefully. And we want to see what happens.
When applying parallel programming techniques, make sure you try things in an environment is similar enough to reality to extrapolate what actual results might be.
Measure the impact, diagnose the impact.
If results weren’t sufficient to meet the desired measures of success outlined in the Goal, then go back to the diagnosis phase.
If results were sufficient, make sure to consider what may be missing. Likely your guess wasn’t the robust final result of what you would need to change in a system. Ask yourself what else needs to be done. If you’re using parallel programming techniques, consider the following:
- What shared resources might lead to race conditions and/or unexpected contention. How can you eliminate these?
- How can you verify the correctness of the solution?
- How can you model actual workloads to validate performance?
- Is the overhead worth it?
- What’s out of your control that you should consider? For example, are you depending on a remote web service that could become overloaded?
These are just a few ideas, you should be able to come up with others. What’s important is to stop and reflect. Make sure the solution is complete and correct.
The beauty of applying this 5 step strategy, we have what matters to guide us through the entire process. We don’t waste time with unnecessary work to make the system as fast as possible. We make it as fast as it needs to be. We can even make a decision that the cost to improve the performance isn’t justified based on the value of the objective. Often we can figure this out in diagnosis before we waste any time trying something out.