Beruflich Dokumente
Kultur Dokumente
In recent times, CPU clock speeds have stagnated and manufacturers have
shifted their focus to increasing core counts. This is problematic for us as
programmers because our standard single-threaded code will not
automatically run faster as a result of those extra cores.
>
Leveraging multiple cores is easy for most server applications, where each
thread can independently handle a separate client request, but is harder on
the desktop because it typically requires that you take your computationally
intensive code and do the following:
>
>
>
PFX Concepts
>
There are two strategies for partitioning work among threads: data parallelism and task parallelism.
PLINQ
>
Parallel LINQ (or PLINQ, as it is called) offers all benefits of LINQ. In addition to that, it enables parallel
execution of LINQ queries to take advantages of multiple processors of the host machine.
>
>
>
>
AsParallel
The AsParallel method is the doorway to PLINQ. It converts data sequence into a ParallelQuery. The
LINQ engine detects the use of a ParallelQuery as the source in a query and switches to PLINQ
execution automatically. You are likely to use the AsParallel method every time you use PLINQ.
>
>
>
>
>
>
>
>
>
>
.
IEnumerable<string> ss = list.AsParallel().AsOrdered().Cast<string>().Where(p =>
p.StartsWith("A")).Select(p => p);
>
>
>
>
Visual
Studio
IDE
Concurrency
Visualizer
Parallel
Parallel LINQ
LINQ
Task Parallel
Library
.NET Framework 4
Concurrency Runtime
ThreadPool
Task Scheduler
Data
Data Structures
Structures
Parallel
Debugger
Tool
Windows
Programming Models
Parallel
Pattern
Library
Data
Data Structures
Structures
Tools
Visual C++ 10
Task Scheduler
Resource Manager
Resource Manager
Operating
System
Key:
Managed
Managed
Agents
Library
Native
Native
Tooling
Tooling
UMS Threads
Array Mapping
int[]
int[] input
input == ...
...
bool[]
bool[] output
output == input.AsParallel()
input.AsParallel()
.Select(x
.Select(x =>
=> IsPrime(x))
IsPrime(x))
.ToArray();
.ToArray();
input:
1
6
3
8
output:
Select
Select
Thread 1
Select
Select
Thread 2
F
F
T
F
Select
Select
Thread N
Sequence Mapping
IEnumerable<int>
IEnumerable<int> input
input == Enumerable.Range(1,100);
Enumerable.Range(1,100);
bool[]
bool[] output
output == input.AsParallel()
input.AsParallel()
.Select(x
.Select(x =>
=> IsPrime(x))
IsPrime(x))
.ToArray();
.ToArray();
Input
Input
Enumerator
Enumerator
Loc
k
Each thread
processes a partition
of inputs and stores
results into a buffer.
Select
Select
Thread 1
Select
Select
Thread 2
Results
1
Results
2
...
Select
Select
Thread N
Results
N
Asynchronous Mapping
var
var qq == input.AsParallel()
input.AsParallel()
.Select(x
.Select(x =>
=> IsPrime(x));
IsPrime(x));
foreach(var
foreach(var xx in
in q)
q) {{ ...
... }}
Select
Select
Thread 1
Input
Input
Enumerator
Enumerator
Loc
k
Select
Select
Thread 2
Results
1
Thread N
Output
Output
Enumerator
Enumerator
MoveNext
MoveNext
Results
2
foreach
foreach
Main
Thread
...
Select
Select
Poll
Poll
Results
N
Thread 1
Input
Input
Enumerator
Enumerator
Loc
k
Op
Op
Thread 2
Results
1
Results
2
Poll
Poll
Output
Output
Enumerator
Enumerator
Ordering
Buffer
MoveNext
MoveNext
...
foreach
foreach
Op
Op
Thread N
Results
N
Main
Thread
Aggregation
int
int result
result == input.AsParallel()
input.AsParallel()
.Aggregate(
.Aggregate(
0,
0,
(a,
(a, e)
e) =>
=> aa ++ Foo(e),
Foo(e),
(a1,a2)
(a1,a2) =>
=> a1
a1 ++ a2);
a2);
res1:
Input
Input
Enumerator
Enumerator
Loc
k
Each thread
computes a local
result.
Aggregate
Aggregate
Thread 1
Aggregate
Aggregate
res2:
result:
Thread 2
...
Aggregate
Aggregate
Thread N
resN:
Search
int
int result
result ==
input.AsParallel().AsOrdered()
input.AsParallel().AsOrdered()
.Where(x
.Where(x =>
=> IsPrime(x))
IsPrime(x))
.First();
.First();
First
First
Thread 1
Input
Input
Enumerator
Enumerator
Loc
k
First
First
Thread 2
resultFound:
Poll
Poll
...
First
First
Thread N
Set
Set
result:
Input
Input
Enumerator
Enumerator
Loc
k
GroupBy
GroupBy
Groups
1
Select
Select
Thread 1
Results
1
Thread 1
Where
Where
GroupBy
GroupBy
Thread 2
...
Groups
2
Select
Select
Thread 2
...
Results
2
output:
bottleneck
> Mitigations:
> Reduce memory allocations
> Turn on server GC
Cache
6
5 7 3 2
Core 1
Thread 2
Memory:
5 7 3 2
Cache
Cache line
5 7 3 2
Core 2
Invalidate
Thread 3
Cache
5 7 3 2
Core 3
Thread 4
Core 4
Cache
5 7 3 2
memory throughput
> By default:
> Array, IList<> are partitioned statically
> Other IEnumerable<> types are partitioned on demand
in chunks