An Insider’s View to Concurrency at Microsoft
description
Transcript of An Insider’s View to Concurrency at Microsoft
![Page 1: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/1.jpg)
An Insider’s View to Concurrency at MicrosoftStephen Toub ([email protected])Parallel Computing PlatformMicrosoft Corporation
![Page 2: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/2.jpg)
Agenda• Why We (I) Care• What We’ve Built for Developers• What We’re Building for Developers
![Page 3: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/3.jpg)
Moore’s Law: Alive and Well
http://upload.wikimedia.org/wikipedia/commons/2/25/Transistor_Count_and_Moore%27s_Law_-_2008_1024.png
![Page 4: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/4.jpg)
MS Apps Using ParallelismExample: Visual Studio• Background
compilation• Regex-based file
search• Graph layout• Reference
highlighting• IntelliSense sorting• Project build system
• Code analysis• Unit testing• …
![Page 5: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/5.jpg)
But it’s not just about core count…• Increasingly connected applications
• More latency• e.g. everything as a service
• More UI responsiveness problems• e.g. the toilet bowl of death
• More scalability issues• Server, Cloud
• e.g. streaming data sources, data distribution• Client
• e.g. modeling interacting biological entities• Async-only APIs
• e.g. Silverlight
![Page 6: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/6.jpg)
The Challenges of Concurrency• A different way of thinking
• Forcing the square peg (concurrency) into the round hole (sequential) is a common (inadequate) mistake
• Parallel patterns are not prevalent, well known, nor easy to implement• CS curriculum is still largely “sequential”: Cormen, et. al; Knuth; etc.
• A different way of writing software• Indeterminate program behavior
• No longer: “A happens, then B happens, then C happens”• It’s just: “A, B, and C happen”
• With distinct costs, too• Deadlocks, livelocks, latent race conditions, priority inversions,
hardware-specific memory model reordering, …
• Businesses have little desire to go deep• Best devs should focus on business value, not concurrency• Need simple ways to allow all devs to write concurrent code
![Page 7: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/7.jpg)
Example: Searching and Sorting
IEnumerable<RaceCarDriver> drivers = ...;var results = new List<RaceCarDriver>();foreach(var driver in drivers){ if (driver.Name == queryName && driver.Wins.Count >= queryWinCount) { results.Add(driver); }}results.Sort((b1, b2) => b1.Age.CompareTo(b2.Age));
![Page 8: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/8.jpg)
Manual Parallel SolutionIEnumerable<RaceCarDriver> drivers = …;var results = new List<RaceCarDriver>();int partitionsCount = Environment.ProcessorCount;int remainingCount = partitionsCount;var enumerator = drivers.GetEnumerator();try { using (var done = new ManualResetEvent(false)) { for(int i = 0; i < partitionsCount; i++) { ThreadPool.QueueUserWorkItem(delegate { while(true) { RaceCarDriver driver; lock (enumerator) { if (!enumerator.MoveNext()) break; driver = enumerator.Current; } if (driver.Name == queryName && driver.Wins.Count >= queryWinCount) { lock(results) results.Add(driver); } } if (Interlocked.Decrement(ref remainingCount) == 0) done.Set(); }); } done.WaitOne(); results.Sort((b1, b2) => b1.Age.CompareTo(b2.Age)); }}finally { if (enumerator is IDisposable) ((IDisposable)enumerator).Dispose(); }
![Page 9: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/9.jpg)
LINQ Solution
IEnumerable<RaceCarDriver> drivers = ...; var results = from driver in drivers where driver.Name == queryName && driver.Wins.Count >= queryWinCount orderby driver.Age ascending select driver;
.AsParallel()
P
![Page 10: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/10.jpg)
DemoPLINQ
![Page 11: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/11.jpg)
Visual Studio 2010Tools, Programming Models, Runtimes
Parallel Pattern Library
Resource Manager
Task Scheduler
Task Parallel Library
Parallel LINQ
Managed NativeKey:
ThreadsOperating System
Concurrency Runtime
Programming Models
ThreadPoolTask Scheduler
Resource Manager
Data Structures D
ata
Stru
ctur
es
Tools
Tooling
ParallelDebugge
r Tool Windows
ProfilerConcurren
cy Visualizer
AsyncAgentsLibrary
UMS Threads
.NET Framework 4 Visual C++ 2010Visual Studio2010
Windows
![Page 12: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/12.jpg)
Investigations for the future…
![Page 13: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/13.jpg)
This is somesynchronous code with .NET 4…public void CopyStreamToStream(Stream source, Stream destination){ byte[] buffer = new byte[0x1000]; int numRead; while ((numRead = source.Read(buffer, 0, buffer.Length)) != 0) { destination.Write(buffer, 0, numRead); }}
![Page 14: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/14.jpg)
This is an expert’s asynchronous code with .NET 4…public void CopyStreamToStream(Stream source, Stream destination){ byte[] buffer = new byte[0x1000]; int numRead; while ((numRead = source.Read(buffer, 0, buffer.Length)) != 0) { destination.Write(buffer, 0, numRead); }}
public IAsyncResult BeginCopyStreamToStream( Stream source, Stream destination){ var tcs = new TaskCompletionSource<object>(); byte[] buffer = new byte[0x1000];
Action<IAsyncResult> readWriteLoop = null; readWriteLoop = iar => { try { for (bool isRead = iar == null; ; isRead = !isRead) { switch (isRead) { case true: iar = source.BeginRead(buffer, 0, buffer.Length, readResult => { if (readResult.CompletedSynchronously) return; readWriteLoop(readResult); }, null); if (!iar.CompletedSynchronously) return; break;
case false: int numRead = source.EndRead(iar); if (numRead == 0) { tcs.TrySetResult(null); return; } iar = destination.BeginWrite(buffer, 0, numRead, writeResult => { if (writeResult.CompletedSynchronously) return; destination.EndWrite(writeResult); readWriteLoop(null); }, null); if (!iar.CompletedSynchronously) return; destination.EndWrite(iar); break; } } } catch (Exception e) { tcs.TrySetException(e); } }; readWriteLoop(null);
return tcs.Task;}
public void EndCopyStreamToStream(IAsyncResult asyncResult){ ((Task)asyncResult).Wait();}
![Page 15: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/15.jpg)
A compiler could do the work for us…
public void CopyStreamToStream(Stream source, Stream destination){ byte[] buffer = new byte[0x1000]; int numRead; while ((numRead = source.Read(buffer, 0, buffer.Length)) != 0) { destination.Write(buffer, 0, numRead); }}
public Task CopyStreamToStream(Stream source, Stream destination){ byte[] buffer = new byte[0x1000]; int numRead; while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0) { await destination.WriteAsync(buffer, 0, numRead); }}
public Task CopyStreamToStream(Stream source, Stream destination){ byte[] buffer = new byte[0x1000]; int numRead; while ((numRead = await source.ReadAsync(buffer, 0, buffer.Length)) != 0) { await destination.WriteAsync(buffer, 0, numRead); }}
![Page 16: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/16.jpg)
Q&A
![Page 17: An Insider’s View to Concurrency at Microsoft](https://reader036.fdocuments.us/reader036/viewer/2022062501/56815ff8550346895dcef7e6/html5/thumbnails/17.jpg)
© 2010 Microsoft Corporation. All rights reserved. Microsoft, Windows, Windows Vista and other product names are or may be registered trademarks and/or trademarks in the U.S. and/or other countries.The information herein is for informational purposes only and represents the current view of Microsoft Corporation as of the date of this presentation. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information provided after the date of this presentation. MICROSOFT MAKES NO WARRANTIES, EXPRESS, IMPLIED OR STATUTORY, AS TO THE INFORMATION IN THIS PRESENTATION.