MSDN Magazine - October 2007 - (Page 72) This can be written more concisely using the C# query comprehension syntax, in which case the PLINQ version looks like this: IEnumerable data = ; var q = from x in data.AsParallel() where p(x) orderby k(x) select f(x); foreach (var e in q) a(e); To use PLINQ, the query would have to be rewritten like this: IEnumerable data = …; var q = ParallelEnumerable.Select( ParallelEnumerable.OrderBy( ParallelEnumerable.Where(data.AsParallel(), (x) => p(x)), (x) => k(x)), (x) => f(x)); foreach (var e in q) a(e); Once you have made this change, PLINQ will transparently execute the Where, OrderBy, and Select on all of the available processors using classic data parallel evaluation techniques. PLINQ uses deferred execution just like LINQ, meaning the query doesn’t begin running until you foreach over it, call GetEnumerator directly, or force the results into a list through some Using language other API such as ToList comprehensions and or ToDictionary. When the extension methods is a more query executes, PLINQ will arrange for parts of the queconvenient way of writing ry to run on the available queries and makes it easier processors through the hidto move to PLINQ. den use of multiple threads. You don’t even need to understand how all of this is done; you just see better performance and better utilization of the available processors. Though it’s not obvious, the inferred type of q differs between the ordinary LINQ-to-Objects and PLINQ queries shown previously. In the first example, q is typed as IEnumerable , where U is whatever type the f method passed to the Select operator returns. In the second example, however, q is typed as IParallelEnumerable . This usually doesn’t matter: if you’ve declared q to explicitly have type IEnumerable , for instance, the change to AsParallel will still work since IParallelEnumerable derives from IEnumerable . But it does mean that any subsequent use of q will be treated like an IParallelEnumerable . For example, if you subsequently query it, PLINQ will be chosen as the query provider. Note that some LINQ operators are binary—they take two IEnumerable s as input. Join is a perfect example of such an operator. In these cases, the type of the left-most data source determines whether LINQ or PLINQ is used. Thus you need only call AsParallel on the first data source for your query to run in parallel: IEnumerable var q = from x join y select leftData = , rightData = ; in leftData.AsParallel() in rightData on x.a == y.b f(x, y); For obvious reasons, using comprehensions and extension methods is a more convenient way of writing your queries and carries the added benefit of making it much easier to move to PLINQ. And that’s it! These are the only changes required to use PLINQ in place of LINQ-to-Objects. Because LINQ-to-XML exposes XML documents as IEnumerable data structures, everything said so far applies to querying XML content, too. Processing Query Output As already noted, due to deferred evaluation, parallelism doesn’t get introduced until you start processing the output of the query. If you’re familiar with IEnumerable , this equates to calling the GetEnumerator method. There are three basic ways that PLINQ queries can be processed, each leading to a slightly different model for parallelism. The first is pipelined processing, in which case the thread doing the enumeration is separate from the threads devoted to running the query. PLINQ will use many threads for query execution, but will reduce the degree of parallelism by one so that the enumerating thread is not interfered with. For instance, if you have eight processors available, seven of them will run the PLINQ query while the remaining processor runs the foreach loop on the output of the PLINQ query as elements become available. This carries the benefit of allowing more incremental processing of output, thus reducing the memory requirements necessary to hold the results; however, having many producer threads and only a single consumer thread can often lead to uneven work distribution, resulting in processor inefficiency. The second model is stop-and-go processing. In this model, the thread that starts the enumeration joins all of the other threads to execute the query. Once all threads have finished producing the complete set of output, the thread then proceeds to enumerating the output. This has the benefit that all processing power is devoted to creating the output as quickly as possible. It is also slightly more efficient than pipelined processing because there is less incremental synchronization overhead in the implementation: PLINQ can be more intelligent about these things because it knows exactly where the output data is going and how it will be accessed. If the work distribution is uneven between the consumers and producer, this is usually a more appropriate method of consumption. Finally, there is inverted enumeration. A lambda function is provided to PLINQ that is run in parallel, once for each element in the output. This is the most efficient mechanism because there is much more parallelism exposed to PLINQ, and the implementation avoids costly operations such as merging output from multiple threads. But it has the drawbacks that you cannot simply use a foreach loop, you must use a special ForAll API, and you must be careful that the lambdas do not rely on shared state. Otherwise, All of this discussion has assumed you’re using extension methods to write your queries. If you have chosen instead to call methods on the Enumerable class directly, then you will have a little more work to do to move over to PLINQ. In addition to the call to AsParallel, you must also reference the ParallelEnumerable type. For example, imagine the above query was written by calling Enumerable directly: IEnumerable data = …; var q = Enumerable.Select( Enumerable.OrderBy( Enumerable.Where(data, (x) => p(x)), (x) => k(x)), (x) => f(x)); foreach (var e in q) a(e); 72 msdnmagazine PlINQ
Table of Contents Feed for the Digital Edition of MSDN Magazine - October 2007 Cover Contents Toolbox CLR Inside Out Basic Instincts Data Points Cutting Edge Pooled Threads WPF Threads Parallel Linq Parallel Performance Mobile Apps Test Run Foundations Windows with C++ Netting C++ .NET Matters { End Bracket } Net Nuptials MSDN Magazine - October 2007 MSDN Magazine - October 2007 - Contents (Page Cover1) MSDN Magazine - October 2007 - Contents (Page Cover2) MSDN Magazine - October 2007 - Contents (Page 1) MSDN Magazine - October 2007 - Contents (Page 2) MSDN Magazine - October 2007 - Contents (Page 3) MSDN Magazine - October 2007 - Contents (Page 4) MSDN Magazine - October 2007 - Contents (Page 5) MSDN Magazine - October 2007 - Contents (Page 6) MSDN Magazine - October 2007 - Contents (Page 7) MSDN Magazine - October 2007 - Contents (Page 8) MSDN Magazine - October 2007 - Contents (Page 9) MSDN Magazine - October 2007 - Contents (Page 10) MSDN Magazine - October 2007 - Toolbox (Page 11) MSDN Magazine - October 2007 - Toolbox (Page 12) MSDN Magazine - October 2007 - Toolbox (Page 13) MSDN Magazine - October 2007 - Toolbox (Page 14) MSDN Magazine - October 2007 - Toolbox (Page 15) MSDN Magazine - October 2007 - Toolbox (Page 16) MSDN Magazine - October 2007 - CLR Inside Out (Page 17) MSDN Magazine - October 2007 - CLR Inside Out (Page 18) MSDN Magazine - October 2007 - CLR Inside Out (Page 19) MSDN Magazine - October 2007 - CLR Inside Out (Page 20) MSDN Magazine - October 2007 - CLR Inside Out (Page 21) MSDN Magazine - October 2007 - CLR Inside Out (Page 22) MSDN Magazine - October 2007 - CLR Inside Out (Page 23) MSDN Magazine - October 2007 - CLR Inside Out (Page 24) MSDN Magazine - October 2007 - CLR Inside Out (Page 25) MSDN Magazine - October 2007 - CLR Inside Out (Page 26) MSDN Magazine - October 2007 - CLR Inside Out (Page 27) MSDN Magazine - October 2007 - CLR Inside Out (Page 28) MSDN Magazine - October 2007 - CLR Inside Out (Page 29) MSDN Magazine - October 2007 - CLR Inside Out (Page 30) MSDN Magazine - October 2007 - Basic Instincts (Page 31) MSDN Magazine - October 2007 - Basic Instincts (Page 32) MSDN Magazine - October 2007 - Basic Instincts (Page 33) MSDN Magazine - October 2007 - Basic Instincts (Page 34) MSDN Magazine - October 2007 - Basic Instincts (Page 35) MSDN Magazine - October 2007 - Basic Instincts (Page 36) MSDN Magazine - October 2007 - Data Points (Page 37) MSDN Magazine - October 2007 - Data Points (Page 38) MSDN Magazine - October 2007 - Data Points (Page 39) MSDN Magazine - October 2007 - Data Points (Page 40) MSDN Magazine - October 2007 - Data Points (Page 41) MSDN Magazine - October 2007 - Data Points (Page 42) MSDN Magazine - October 2007 - Cutting Edge (Page 43) MSDN Magazine - October 2007 - Cutting Edge (Page 44) MSDN Magazine - October 2007 - Cutting Edge (Page 45) MSDN Magazine - October 2007 - Cutting Edge (Page 46) MSDN Magazine - October 2007 - Cutting Edge (Page 47) MSDN Magazine - October 2007 - Cutting Edge (Page 48) MSDN Magazine - October 2007 - Cutting Edge (Page 49) MSDN Magazine - October 2007 - Cutting Edge (Page 50) MSDN Magazine - October 2007 - Cutting Edge (Page 51) MSDN Magazine - October 2007 - Cutting Edge (Page 52) MSDN Magazine - October 2007 - Cutting Edge (Page 53) MSDN Magazine - October 2007 - Pooled Threads (Page 54) MSDN Magazine - October 2007 - Pooled Threads (Page 55) MSDN Magazine - October 2007 - Pooled Threads (Page 56) MSDN Magazine - October 2007 - Pooled Threads (Page 57) MSDN Magazine - October 2007 - Pooled Threads (Page 58) MSDN Magazine - October 2007 - Pooled Threads (Page 59) MSDN Magazine - October 2007 - Pooled Threads (Page 60) MSDN Magazine - October 2007 - Pooled Threads (Page 61) MSDN Magazine - October 2007 - Pooled Threads (Page 62) MSDN Magazine - October 2007 - Pooled Threads (Page 63) MSDN Magazine - October 2007 - Pooled Threads (Page 64) MSDN Magazine - October 2007 - Pooled Threads (Page 65) MSDN Magazine - October 2007 - WPF Threads (Page 66) MSDN Magazine - October 2007 - WPF Threads (Page 67) MSDN Magazine - October 2007 - WPF Threads (Page 68) MSDN Magazine - October 2007 - WPF Threads (Page 69) MSDN Magazine - October 2007 - Parallel Linq (Page 70) MSDN Magazine - October 2007 - Parallel Linq (Page 71) MSDN Magazine - October 2007 - Parallel Linq (Page 72) MSDN Magazine - October 2007 - Parallel Linq (Page 73) MSDN Magazine - October 2007 - Parallel Linq (Page 74) MSDN Magazine - October 2007 - Parallel Linq (Page 75) MSDN Magazine - October 2007 - Parallel Linq (Page 76) MSDN Magazine - October 2007 - Parallel Linq (Page 77) MSDN Magazine - October 2007 - Parallel Linq (Page 78) MSDN Magazine - October 2007 - Parallel Performance (Page 79) MSDN Magazine - October 2007 - Parallel Performance (Page 80) MSDN Magazine - October 2007 - Parallel Performance (Page 81) MSDN Magazine - October 2007 - Parallel Performance (Page 82) MSDN Magazine - October 2007 - Parallel Performance (Page 83) MSDN Magazine - October 2007 - Parallel Performance (Page 84) MSDN Magazine - October 2007 - Parallel Performance (Page 85) MSDN Magazine - October 2007 - Parallel Performance (Page 86) MSDN Magazine - October 2007 - Parallel Performance (Page 87) MSDN Magazine - October 2007 - Parallel Performance (Page 88) MSDN Magazine - October 2007 - Parallel Performance (Page 89) MSDN Magazine - October 2007 - Parallel Performance (Page 90) MSDN Magazine - October 2007 - Mobile Apps (Page 91) MSDN Magazine - October 2007 - Mobile Apps (Page 92) MSDN Magazine - October 2007 - Mobile Apps (Page 93) MSDN Magazine - October 2007 - Mobile Apps (Page 94) MSDN Magazine - October 2007 - Mobile Apps (Page 95) MSDN Magazine - October 2007 - Mobile Apps (Page 96) MSDN Magazine - October 2007 - Mobile Apps (Page 97) MSDN Magazine - October 2007 - Mobile Apps (Page 98) MSDN Magazine - October 2007 - Mobile Apps (Page 99) MSDN Magazine - October 2007 - Mobile Apps (Page 100) MSDN Magazine - October 2007 - Test Run (Page 101) MSDN Magazine - October 2007 - Test Run (Page 102) MSDN Magazine - October 2007 - Test Run (Page 103) MSDN Magazine - October 2007 - Test Run (Page 104) MSDN Magazine - October 2007 - Test Run (Page 105) MSDN Magazine - October 2007 - Test Run (Page 106) MSDN Magazine - October 2007 - Test Run (Page 107) MSDN Magazine - October 2007 - Test Run (Page 108) MSDN Magazine - October 2007 - Test Run (Page 109) MSDN Magazine - October 2007 - Test Run (Page 110) MSDN Magazine - October 2007 - Test Run (Page 111) MSDN Magazine - October 2007 - Test Run (Page 112) MSDN Magazine - October 2007 - Test Run (Page 113) MSDN Magazine - October 2007 - Test Run (Page 114) MSDN Magazine - October 2007 - Foundations (Page 115) MSDN Magazine - October 2007 - Foundations (Page 116) MSDN Magazine - October 2007 - Foundations (Page 117) MSDN Magazine - October 2007 - Foundations (Page 118) MSDN Magazine - October 2007 - Foundations (Page 119) MSDN Magazine - October 2007 - Foundations (Page 120) MSDN Magazine - October 2007 - Foundations (Page 121) MSDN Magazine - October 2007 - Foundations (Page 122) MSDN Magazine - October 2007 - Foundations (Page 123) MSDN Magazine - October 2007 - Foundations (Page 124) MSDN Magazine - October 2007 - Windows with C++ (Page 125) MSDN Magazine - October 2007 - Windows with C++ (Page 126) MSDN Magazine - October 2007 - Windows with C++ (Page 127) MSDN Magazine - October 2007 - Windows with C++ (Page 128) MSDN Magazine - October 2007 - Windows with C++ (Page 129) MSDN Magazine - October 2007 - Windows with C++ (Page 130) MSDN Magazine - October 2007 - Windows with C++ (Page 131) MSDN Magazine - October 2007 - Windows with C++ (Page 132) MSDN Magazine - October 2007 - Netting C++ (Page 133) MSDN Magazine - October 2007 - Netting C++ (Page 134) MSDN Magazine - October 2007 - Netting C++ (Page 135) MSDN Magazine - October 2007 - Netting C++ (Page 136) MSDN Magazine - October 2007 - .NET Matters (Page 137) MSDN Magazine - October 2007 - .NET Matters (Page 138) MSDN Magazine - October 2007 - .NET Matters (Page 139) MSDN Magazine - October 2007 - .NET Matters (Page 140) MSDN Magazine - October 2007 - .NET Matters (Page 141) MSDN Magazine - October 2007 - .NET Matters (Page 142) MSDN Magazine - October 2007 - .NET Matters (Page 143) MSDN Magazine - October 2007 - Net Nuptials (Page 144) MSDN Magazine - October 2007 - Net Nuptials (Page Cover3) MSDN Magazine - October 2007 - Net Nuptials (Page Cover4)
For optimal viewing of this digital publication, please enable JavaScript and then refresh the page. If you would like to try to load the digital publication without using Flash Player detection, please click here.