Earth Toned Threads - .NET Parallel Extensions
Back in the pre-Facebook era, there was a certain political figure who has accused of suddenly dressing in earth tones on the request of an advisor who thought that these muted colors were reassuring to audiences. This plan, especially after it was revealed, did not have the desired effect.
However, code is by nature easier to dress up than a person. And with the .NET Parallel Extensions, released as an add-on to the 3.5 .NET Framework as a CTP in December, Microsoft is attempting to take the edge off of threads by clothing them in an extra layer of reassuringly subdued abstraction.
This weekend, I attended a session of the SoCal Rock & Roll Code Camp at Cal State Fullerton about these newly released extensions. The presenter, Rinat Shagisultanov, gave a quick overview of what was in the extensions, as well as some working examples. There is a lot in there, so check it out yourself for all the details, but what really stuck out to me was a point Rinat made early in the session. To paraphrase, his point was that Microsoft already gave us the Framework with its threading capabilities and this extension did not change this, rather it gave us some nice building blocks on top of the existing Framework to make writing the code less intimidating.
The curious might ask, like what? The most basic example would be the addition of the Parallel.ForEach construct , which can be used to quickly transform a strictly sequential execution path into a parallel one. This construct gets a little more complicated when you are actively working with shared state, but the basic idea is that the Parallel Extensions spins out a thread for each core and distributes the work between the cores without you having to write the plumbing code. There is also PLINQ (Parallel LINQ) for querying objects in parallel, as well as the Task, Future and TaskManager objects which allow for finer grained control of the distribution of items of work in parallel. (1)
I won't get any further into the details of the API's at this point (although perhaps I will in a later post) because I want to return to the idea these extensions are really less intimated or earth toned threads. Threads could use the help, as they are pretty universally regarded as one of those "hard" topics in programming.
Lots of programmers cringe when they see code in an application that starts spinning out threads. They begin to imagine the nightmares of debugging seemingly random errors and designing the appropriate access schemes for shared memory. It is somewhat a badge of honor to brave the depths of multi-threading and come out with an application that is reasonably stable.
If threads are to be one of the prime mechanisms for parallelism and the importance of parallelism is increasing with multi-core machines, isn't it bad that they are perceived to be so difficult and obtuse? One answer to that question is that they are not really all that hard and most programmers are just stupid. I call this the unintentionally dismissive guru stance; once you've figured something out, you cannot really remember how hard it was for you to do it.
Another answer is that they are hard, but that's OK, because threads are too powerful and dangerous for the average programmer. This is the intentionally dismissive grizzled vet stance; you've earned your stripes working on multi-threaded applications and you don't need some newbie bumbler coming along and fouling things up.
The answer that Microsoft has given with the Parallel Extensions is yes, threads hard and yes that's a problem, so here's some tools that give you a chance to get the parallelism you want (using threads under the covers), but only dive as deep into the intricacies of the threads as you absolutely have to. I call this the populist approach; give something to the masses (even if it's not perfect), at the possible expense of being looked down upon by the elite.
I have not gotten a chance to dig deep into the Parallel Extensions yet, but apparently it is due to be incorporated into the next base distribution of the Framework and what I have seen looks really promising. These extensions, especially when you deal with shared state, will still open up some dangerous traps for the unwary, but they lower the bar for entry and provide some nice base abstractions to work with. In fact, coupled with WCF services, you can see the outline of a .NET grid computing architecture with multi-threaded services distributed across multiple machines pretty easily out of the box. (2) So do yourself a favor and add this CTP to your long list of new parts of the .NET Framework to learn.
(1) Rinat gave a more comprehensive breakdown of what these different API's are and what they could be used for, so any confusion you may experience in reading my description is of my own doing. The slides and code he presented in the session are on his blog at: Code Camp, Fullerton, CA Jan 2008: Concurrent Programming in .NET (Parallel FX)
(2) Some would actually argue that you should not really use multi-threading paradigms anywhere for concurrency; everything should be based on message passing between processes and thereby avoid the problems of accessing shared memory. That is an argument I am not prepared to take on, but for a strong version of the pro-argument see the language Erlang, which is built around the principles of no-shared memory, processes and message passing.