DEV314: Manycore and the Microsoft .NET Framework 4 with

IEnumerable<Record> records = GetRecords();
List<Result> results = new List<Result>();
foreach(Record record in records)
{
Result res = ProcessRecord(record); // non-trivial computation per record
if (Filter(res)) results.Add(res); // check if result matches our criteria, if so add it into results
}
// can also be expressed as a simple LINQ statement
List<Result> results = records.Select(rec => ProcessRecord(rec)).Where(res => Filter(res)).ToList();
IEnumerable<Record> records = GetRecords();
List<Result> results = new List<Result>();
int numWorkers = Environment.ProcessorCount;
int activeWorkers = numWorkers;
IEnumerator<Record> enumerator = records.GetEnumerator();
ManualResetEvent completionEvent = new ManualResetEvent(false);
for(int i = 0; i < numWorkers; i++) {
ThreadPool.QueueUserWorkItem(delegate { // launch P workers
while(true) {
Record currentRecord;
lock (enumerator) { // grab a record under the lock before processing it
if (!enumerator.MoveNext()) break;
currentRecord = enumerator.Current;
}
Result res = ProcessRecord(currentRecord); // non-trivial computation per record
if (Filter(res))
// check if result matches our criteria
{
lock(results) results.Add(res); // if so add it into results list under a lock
}
}
if (Interlocked.Decrement(ref activeWorkers) == 0) completionEvent.Set();
});
}
completionEvent.WaitOne();
// wait until all workers are done
SAME CODE PARALLELIZED USING PLINQ
// Parallelized LINQ query
List<Result> results =
records.AsParallel().Select(rec => ProcessRecord(rec)).Where(res => Filter(res)).ToList();
for (int i = 0; i < 100; i++) DoWork(i);
Parallel.For(0, 100, i => DoWork(i));
foreach (Record rec in src) DoWork(rec);
Parallel.ForEach(src, rec => DoWork(rec));
{
// independent statements
A();
B();
C();
Parallel.Invoke( () => A(),
() => B(),
() => C());
}
Record[] results = source
.Select(rec => TransformFunc(rec))
.ToArray();
Record[] results = source.AsParallel()
.Select(rec => TransformFunc(rec))
.ToArray();
PARALLEL LOOPS
Parallel.For(0, 100, i => DoWork(i));
Parallel.ForEach(src, rec => DoWork(rec));
Thread 1
i=0
i=1
i=C+1
i=C+2
Thread 1
i=2
rec
1
rec
P+1
rec
2P+1
Thread 2
i=C+3
src
Thread P
Thread P
i=P*C+1
i=P*C+1
i=P*C+2
rec
P
rec
2P
rec
3P
// Breaking from a parallel loop
Parallel.For(0, 1000, (i, state) => { if (SearchFunc(i)) state.Stop(); }
// Controlling Degree Of Parallelism
ParallelOptions po = new ParallelOptions() { MaxDegreeOfParallelism = 4 };
Parallel.ForEach(source, po, element => ProcessRecord(element) }
// Using thread local state
Dictionary<Guid, int> counts = GetGlobalCounts();
Parallel.ForEach(enumSource,
() => {
//once per worker thread local init
return new List<Result>();
},
(record, loopState, threadLocal) => {
// actual loop body
var result = ProcessRecord(record);
if (result.InterestingFlag)
threadLocal.Add(result); //cache results
},
(threadLocal) =>
{
//end of loop, once per worker combine delegate
lock (counts)
foreach (Result res in threadLocal)
counts[res.GUID] += res.Count;
});
PARALLEL LINQ
HOW PLINQ WORKS
(from x in src.AsParallel() where f(x) select y(x)).Sum();
Thread 1
where f(x)
select y(x)
Sum()
Sum()
src
Thread P
where f(x)
select y(x)
Sum()
PARALLEL LINQ (cont’d)
Enqueue
Dequeue
T3 T2 T1
Global Queue (FIFO)
Thread 1
Dispatch Loop
Thread 2
Dispatch Loop
Thread N
Dispatch Loop
Enqueue
Thread 1
Dispatch Loop
Dequeue
Thread 2
Dispatch Loop
Thread N
Dispatch Loop
T3 T2 TT14
Global Queue (FIFO)
Dequeue
Enqueue
T5
T6
T7
T8
Steal
Thread 1
Local Queue (LIFO)
Steal
Thread 2
Local Queue (LIFO)
Steal
Thread N
Local Queue (LIFO)
Thread-safe, scalable collections
Synchronization
Partitioning
Initialization
Cancellation
// Producer consumer pattern
BlockingCollection<string> bc = new BlockingCollection<string>();
// Start the producer Task
Task t1 = Task.Factory.StartNew(() =>
{
while(!streamReader.EndOfStream)
bc.CompleteAdding();
});
bc.Add(streamReader.ReadLine());
// Start the consumer Task
Task t2 = Task.Factory.StartNew(() =>
{
try
{
// Consume from the blocking collection
while (true) Console.WriteLine(bc.Take());
}
catch (InvalidOperationException)
{
// IOE thrown from Take() indicated completed collection
Console.WriteLine("That's All!");
}
});
http://www.microsoft.com/visualstudio/en-us/
http://blogs.msdn.com/b/somasegar/
http://msdn.com/data
http://blogs.msdn.com/adonet
http://blogs.msdn.com/astoriateam
http://blogs.msdn.com/efdesign
www.microsoft.com/teched
www.microsoft.com/learning
http://microsoft.com/technet
http://microsoft.com/msdn
Sign up for Tech·Ed 2011 and save $500
starting June 8 – June 31st
http://northamerica.msteched.com/registration
You can also register at the
North America 2011 kiosk located at registration
Join us in Atlanta next year