Objective
In this article, I will provide the summary about Parallel Programming in C# 4.0 with a comparative study of the PFX (Parallel Programming Framework) technologies with each other. My intention of writing this article is to help you to decide which PFX technology you should use in which scenario.
I am assuming that you are aware of the PFX technologies. So here, I will not explain them in detail. Rather, I would provide the summary of them to revise the concepts. Before that, I would explain some important concepts of Parallel Programming.
Parallel Programming
Programming to leverage multicores or multiple processors.
Parallel Programming uses one of the two strategies for partitioning work among threads: data parallelism and task parallelism.
Data Parallelism
- Divide data to be processed into chunks and allocate those chunks to separate threads for processing.
- Structured parallelism, which means that parallel work units start and finish in the same place in your program.
- Simpler and less error prone and allows you to farm the difficult job of partitioning and thread coordination and result coalition out to libraries.
Task Parallelism
- Divide tasks and allocate those tasks to separate threads for processing.
- Unstructured parallelism, meaning that parallel work units may start and finish in places scattered across your program.
Below is the table which summarizes PLINQ, Parallel class and Task Parallel Library.
| PFX (Parallel Framework) = PLINQ + TPL + Concurrent Collection + SpinLock and SpinWait |
| Task Parallel Library (TPL) |
Structured Data Parallelism | |
| PLINQ | Parallel Class | Task Parallelism |
Partition | Y | Y | N |
Collation | Y | N | N |
Declarative/
Imperative | Declarative — You simply declare that you want to parallelize your work and framework does paritioning and collation for you. | Imperative- You need to explicitly write code to partition or collate. |
About | * Implement Parallel Programming with simple LINQ without worrying about complexities involved.
* PLINQ requires exactly N threads, which is specified by using the WithDegreeOfParallelism()
* PLINQ stores your results in a thread-safe manner automatically.
* By default, ordering is not preserved. You need to use AsOrdered() after AsParallel() . | * Parallel requires N or less threads, which is specified by using ParallelOptions.MaxDegreeOfParallelism .
* Parallel.ForEach expects you to store your results in a thread-safe manner.
* Ordering cannot be preserved. | * Cooperative cancellation.
* Wait on a set of tasks — without a signaling construct.
* Attach “continuation” task(s).
* Schedule a continuation based on multiple antecedent tasks.
* Propagate exceptions to parents, continuations, and task consumers. |
Use | * When you want to execute operations in parallel and then wait for them to complete. This includes non-CPU-intensive tasks such as calling a web service.
* When problem is embarrassingly parallel. | You want to run some operation on a pooled thread, and also to manage a task’s workflow through continuations and parent/child tasks. |
* For order preservation using AsOrdered() .
* For stream processing.
* For Operating over Two Collections. | * For performing Independent Actions.
* For Thread-Local state access. | |
How to use | Simply call AsParallel() on the input sequence and then continue the LINQ query as usual. | Parallel.Invoke – executes an array of delegates in parallel.
Parallel.For - parallel implementation of a C# for loop.
Parallel.ForEach - parallel implementation of a C# foreach loop. | Task for unit for work.
<span>Task<TResult></span> for a unit for work with a return value.
<span>TaskFactory</span> for creating tasks.
<span>TaskFactory<TResult></span> For creating tasks and continuations with the same return type.
<span>TaskScheduler</span> For managing the scheduling of tasks.
<span>TaskCompletionSource</span> For manually controlling a task’s workflow. |
Exception | If a PLINQ query throws an exception, it’s rethrown as an AggregateException whose InnerExceptions property contains the real exception(s). | | |
|
Concurrent Collection - You want a thread-safe queue, stack, or dictionary. |
SpinLock and SpinWait - You want to implement producer/consumer structures. |
In my next articles, I would explain these PFX technologies in detail. Hope it helps you decide which technology to use in which scenario with reasoning.