Distributed Memory Programming

8.1 Program Hygiene
 
"It must be emphasized that the machine does not think for itself. It may exercise some degree of judgment and discrimination, but the situations in which these are required, the criteria to be applied, and the actions to be taken according to the criteria, have all to be foreseen in the program of operating instructions furnished to the machine. Use of the machine is no substitute for thought on the basic organization of a computation, only for the labour of carrying out the details of the application of that thought."

Douglass R. Hartree, Moore School lecture, Univ. of Penn., 9 July 1946.

Fifty years later, and it sounds like it could have been said yesterday ... or tomorrow.

The focus now turns to practical matters pertaining to achieving good, solid working distributed code. Some of the points will seem blatantly obvious, and some are going to need to be learned by doing rather than simply hearing or reading; all of them, however, and many more that we don't have time to go into here, are essential considerations when designing and building a distributed application.

Helpful hint: if you haven't put at least 75% of the entire project time into the design phase, then the whole development cycle will almost certainly have taken longer (much longer, especially the debugging stage) than it would have if you had. Everything from high-level "this goes in and this should come out" down to pseudo-coded modules with defined parameter lists (maybe not well-defined, but you should know what kind of information is expected by each routine, and what each one provides in return). Don't be reluctant to engage in desk-checking: construct a simple enough scenario that you can run it through your pseudo-code model step-by-step, and make sure that things are happening the way you expect them to. Only then, when you've demonstrated that a realistic-if-simple case is handled correctly by your model, should you then proceed to turn that model into a working application.

The really nice thing about this approach is that you can write the code one-module-at-a-time, and re-run your testcase with the module-model replaced by the actual code, verify that the code works as expected, and then replace it with the model again, that much more sure that, when it comes time to check the code for another module, you can use the model for the earlier one without any loss of certainty in its operation.

Okay, I'll admit it: this is a shameless plug for what's known as the "Top-Down Approach", and I don't feel at all guilty for pushing it. This ability to treat significant portions of the whole application as not-well-understood, plug-and-play modules is extremely important when you move into a distributed computing environment, because that's the way it looks to one piece of your application sitting on that processor over there, and alternatively pitching and catching message-packets to/from other modules scattered around the network-landscape: from any one module, everything else looks like a black box, with a catcher's mitt on one side and a pitching arm on the other ... so it only makes sense to design and desk-check with those same considerations in mind.