Apparently (and I do not pretend to understand the details) we have pretty much reached the limit of how fast a single CPU can go. So chip manufacturers have responded by putting more of them in our computers. These days “dual core” (ie two CPUs on one chip) is mainstream and quad cores (yes, that’s four CPUs on one chip, though Intel seem to feel that “quad core” is a bit too obvious and so go for names like Core 2 Xtreme Wibbly Wobbly, but that’s marketing for you) are not far behind. Given the way these things tend to scale, the number of cores will likely grow thus: 8, 16, 32, 64, 128 etc. So in just a decade or so’s time, we might well have over a hundred CPUs inside our computers. “So what?” you might ask. Well the answer is simple: what are they supposed to do exactly?
In order to make use of lots of cores, the computer needs lots of parallel tasks to perform. Writing code that executes lots of separate parts in parallel is very hard though. Not only is there the challenge of breaking the problem up into a series of parallel solutions, those solutions must share resources, which requires locks. Locks are a programming nightmare as anyone who has had to use them will know, with deadlocks and race conditions being the more obvious problems. So with all this extra parallelism, what we really need is a good level of abstraction between the developer and the parallel solution. Back in the bad old days of a few years back, we might have expected the Mac and Linux to get great solutions to this soon after the emergence of multi-core CPUs and then, five years later, Microsoft would nick these ideas, turn them into a disastrous mess of an implementation and then release them to near universal acclaim over how brilliant they were. These days, people’s expectations are far higher and Microsoft’s ability to respond in a timely fashion is so much better. The release of the CTP of the Task Parallel Library is an obvious example of this.
The Task Parallel Library (ParallelFX) brings two features to the .NET environment that allow the developer to effortlessly make use of multiple core CPUs. The first are parallel FOR and FOREACH functions. They work pretty much like a transitional for loop, except that some iterations are run in parallel when more than one core is available. The behind-the-scenes code handles scaling the parallelism according the number of cores on the target machine; the developer simply writes their for loop as standard. The second innovation is PLing: a parallel version of Linq. Again the behind-the-scenes code does all the clever parallel stuff. The developer just tells the compiler that the Linq query ought to be considered for running in parallel and the code adapts to the target machine’s hardware.
UPDATE: there is a fairly major “gotcha” when using Parallel.For() that affects loops with a small number of iterations. Read about it here.