There’s trouble on the way, concerning the commercial application of massive parallelism. I first became aware of this in the early to mid 1990s, when firms like Sequent were making SMP machines with tens of “cores” (as we’d call them today) and people were also getting interested in making use of all the cycles going to waste in networked workstations, especially at night. Today we have Beowulfs, BOINC and Sun’s Grid.
The trouble with parallelism is that it’s hard. There are some problems that are embarrassingly parallel - they fall apart into readily parallelizable subproblems which can easily be farmed out. But not all problems are like this. Some progress is possible by being very, very clever at the OS level of SMP machines - much of the SCO FUD antics in the recent legal cases revolved around this. To an extent it’s possible to conceal parallelism from the user (a programmer in this case) while still getting the benefit.
In general though, to get the benefit of parallelism we have to explicitly think about how we can make our algorithms parallel and code them accordingly. That’s well tricky, requiring in-depth contemplation of the structure of the problem. The results are also unstable. We can design efficient parallel algorithms with plenty of skull-sweat on the part of a dedicated and cunning person, but then a small change to the requirement can invalidate the entire design, meaning that the skull-sweating has to start all over again.
Notice that the presence of a parallelizing framework (like BOINC) does nothing to solve this problem. A framework can help us to dispatch and harvest jobs once they have been designed, but it cannot help us design them.
About 10 years ago these problems combined with the stress based descent into busy-work displacement activities that I have described to produce a truly bizarre result. At the time massively parallel applications were considered “big iron” stuff, suitable for farming out to Facilities Management or body shop outfits, which didn’t have a clue how to go about solving research problems. Because they were unable to address the real problems, they started “following the procedure”. Each element of a simulation (a car, a soldier, sometimes even a molecule) were represented by objects. These objects sent messages to other objects, usually via CORBA or some other unknowable and bloated horror. The “requirement” was then transliterated into sets of messages, and the whole thing was set to run.
These parallel applications usually ran two or three orders of magnitude too slowly to be any use to anyone. The lifecycle problem never emerged, because they took so long to write that they rarely completed one cycle (usually at a cost of millions). Wretched, miserable failure.
More and more bloated “middleware” can dispose of the available cycles for us, but not in a productive way. It’s sobering to realize that modern multi-core servers running Enterprise Java Beans to deliver web apps to browsers often underperform early CICS talking to IBM 3270s 30 years ago.
Until recently, this problem - that we do not know how to write parallel apps in an efficient and repeatable way - has been a sleeping dragon. Some of us have seen how bad it gets, but the problem hasn’t come up so often so we don’t worry about it. But there are good physical reasons why processors are getting more cores rather than more GHz these days, so the problem will soon become acute. Here’s a video clip that had me shouting “It is later than you think!” and similar Toynbeeisms. An Intel employee is holding a Teraflops, spread over 80 cores, in his hands:
Like David Bowie sang, “Five years, that’s all we’ve got.” Then we’re going to look like total plonkers who can’t make use of massively parallel resources. We urgently need a new departure in production programming techniques, and I reckon functional programming languages have to be the starting point. Functional programming helps by encouraging us to naturally decompose problems into chunks that can be parallelized, because they retain partial computations until the results are needed. Such partial computations or “thunks” have the possibility to be executed in parallel.
Now I’m not saying that functional languages are a panacea which will make the problems go away. Rather, they are a place to start learning how to make use of such amazing resources, which offer a snowflake’s chance of success. And in production environments, today we have nothing. Having a worker thread in your MFC app is nothing to be proud of - think how hard it was to get it right, the locking, race condition and harvesting issues you had to deal with. There’s a core on my MacBook that hardly gets used at all. So this is an exciting time - there’s work to be done, problems to solve!
So I started looking at the options. Lisp and Scheme - which Lisp and Scheme? There are so many… OCaml is popular today, but to me (and I’m not an expert) it seemed too Java-ish. I’m looking for something that will kick dirt in the face of C, running on SMP machines. As a language for preparing for the future F# is dripping with proprietary evil. So Haskell. GHC is awesome, runs everywhere, and seems to produce compiled programs that take about twice as long as the same thing written in C. (That’s OK - it’s less than one Moore cycle and it takes most organizations over a year to decide to do something.) It’s obviously very powerful, has an intelligent and active community, and issues of parallelization and concurrency are under active investigation by said community. Chapter 24 of Beautiful Code left me suitably impressed. So I decided I had to learn Haskell.
Oh dear. I’ve not blogged for a while, have I? There’s a problem learning Haskell. In part I think it comes from the very richness and flexibility of the language. In Surely You’re Joking, Mr. Feynman! Richard Feynman describes a difficulty he had when he was first learning to draw:
I noticed that the teacher didn’t tell people much (the only thing he told me was my picture was too small on the page). Instead, he tried to inspire us to experiment with new approaches. I thought of how we teach physics: We have so many techniques — so many mathematical methods — that we never stop telling the students how to do things. On the other hand, the drawing teacher is afraid to tell you anything. If your lines are very heavy, the teacher can’t say, “Your lines are too heavy,” because some artist has figured out a way of making great pictures using heavy lines. The teacher doesn’t want to push you in some particular direction.
People who already know Haskell seem to be in the same state as Feynman’s art teacher. Rather than giving an example of how to open a file, they prefer to enthuse about what they call their “monad complexity”. The innocent newcomer can trawl through reams of this stuff, never discover how to open a file, but come away convinced that it is very, very hard. I’m not the only person who has formed this wrong impression. A recent thread on Reddit Why don’t you use Haskell reflected this:
I think this exactly hits the nail on the head. Haskell is a beautiful language, and I enjoy working with it just for the mind stretch that it gives, but the conceptual overhead and cost of entry is high — it’s got a very steep learning curve at the beginning. By comparison, the “hot” languages right now (Python, Ruby) are all much friendlier to someone new.
Haskell itself appears to be overly complicated in many ways, though I admit I have no real experience with the language.
Because after I learned quite a bit, enjoying the mind-bending in monads and the type system, I looked at the code for a real-world but very simple problem (a front-end for a shell mp3 player), and it was far harder to read and far less elegant than all the beautiful example code.
I should say that I’m quite confident that the above comment is not correct. I just wrote a little real world program in Haskell, and it’s way clearer than the C++ equivalent. However, I based it on a very, very helpful insight I got from the haskell-cafe mailing list. Until then, my attempt to write a real world program based on all the “monad complexity” stuff stalled on trying to open the input file.
Because it’s a hard language to work in. It’s by no means as hard as people make it out to be, and many times it’s easier than the competition, but I find that more often than not I have to work very hard to do basic things in Haskell.
There are plenty of other reasons on that thread, but most of them I’m dismissing for my purposes. Of course other people at work don’t use it at the moment. Other people at work won’t be able to make use of a Teraflops the size and shape of a pizza either. Shifting to functional thinking is an intellectual challenge, but so is trying to do massively parallel complex non-linear ray tracing work in C++. In fact it’s so complex it’s doomed. It’s the barrier to entry caused by the perceived complexity of basic tasks that is the big problem. What’s missing is the Haskell equivalent of:
int main(int argc, char **argv)
while((c = getchar()) != EOF)
I could bang on about that for hours, and make you think you have to be Alan Turing to understand it. Or I could just show the code.
Another metaphor for the current barrier to entry and its opportunity cost occurred to me as I was struggling with my program. Perhaps you will doubt my interpretation of history, but if so, please try to see my point!
In the 1980s there was a Scottish band with a cult following called the Cocteau Twins. (They weren’t twins and they weren’t called Cocteau.) Their music was a unique conception of sound, and while it worked for some people, most couldn’t get their heads round it. There was a whole secondary poetry that grew up around people guessing what the words might be! Here’s Heaven or Las Vegas - mature Cocteaus from about 1990:
Then in 1993 they released an albumn called Four Calendar Cafe. I reckon it will be years before the albumn’s importance will be fully appreciated. It did for the audience what The Velvet Underground & Nico did for other musicians in its day. It educated us. Here’s Evangeline, from Four Calendar Cafe:
Once we had been educated, their whole back catalogue became accessible, unleashing a tsunami of richness and subtlety on mid-1990s Britain. The old cult fans weren’t entirely impressed. The Wikipedia entry remembers,
The band’s seventh LP, Four-Calendar Café, was released in late 1993. It was a departure from the heavily-processed, complex and layered sounds of Blue Bell Knoll and Heaven or Las Vegas, featuring clearer and more minimalistic arrangements. This, along with the record’s unusually comprehensible lyrics, led to mixed reviews for the album: Some critics accused the group of selling out and producing an ‘accessible album,’ while others praised the new direction as a felicitous development worthy of comparison with Heaven or Las Vegas.
The Cocteaus suddenly raised the bar, and in doing so they created a space where others could do equally interesting and challenging things, and also be understood. There was a new energy building in Bristol, and we got a new, complex inner-city sound. A strange sound, where a line between Portishead and Willam Blake passes through Lee Marvin:
Massive Attack also came from Bristol. Time was, whenever you had half a dozen people and a surface you’d get a Karmacoma:
Sarah McLachlan suddenly went big too, after years of solid work, and unlike Tori Amos she never needed housing up. Remember this?
Is it really fair to say the Cocteaus made a space where these things were possible, given that the people collectively tagged the Bristol Sound denied there was any such movement? To support my argument, consider the simpatico when the Cocteaus’ Elizabeth Fraser guested on Massive Attack’s Teardrop:
None of this in any way detracted from the high aspirations that the Cocteaus had always followed. In fact it became more powerful - the enabling technology which allows Elf song to run without a hypervisor on Klingon speaking brains (don’t worry - this is not a spoiler. As Feynman said, knowledge only adds, never subtracts):
I do like YouTube. It’s ever so handy for those of us who tend to think in tunes!
My point is that the functional programming world, and Haskell in particular, is ready to and must become the dominant force in programming, like OO helped us tackle the complexity problems of 20 years ago. Everything is ready to go. But the current barrier to entry is preventing the necessary growth. The barrier is nothing to do with “monad complexity”. Most people who use the C++ STL don’t really understand the complex template metaprogramming cleverness that’s going on behind the scenes, but they can look at some examples and see how to do it. We don’t need more tutorials that bang on about “monad complexity”. We need a small corpus of simple example programs to show us how the various features and idioms fit together. Not every possible way, just the ways that working programmers might use the language to address common real world problems.