An Insiders View to Concurrency at Microsoft Stephen

  • Slides: 17
Download presentation
An Insider’s View to Concurrency at Microsoft Stephen Toub (stoub@microsoft. com) Parallel Computing Platform

An Insider’s View to Concurrency at Microsoft Stephen Toub (stoub@microsoft. com) Parallel Computing Platform Microsoft Corporation

Agenda • Why We (I) Care • What We’ve Built for Developers • What

Agenda • Why We (I) Care • What We’ve Built for Developers • What We’re Building for Developers

Moore’s Law: Alive and Well http: //upload. wikimedia. org/wikipedia/commons/2/25/Transistor_Count_and_Moore%27 s_Law_-_2008_1024. png

Moore’s Law: Alive and Well http: //upload. wikimedia. org/wikipedia/commons/2/25/Transistor_Count_and_Moore%27 s_Law_-_2008_1024. png

MS Apps Using Parallelism Example: Visual Studio • Unit testing • Background compilation •

MS Apps Using Parallelism Example: Visual Studio • Unit testing • Background compilation • … • Regex-based file search • Graph layout • Reference highlighting • Intelli. Sense sorting • Project build system • Code analysis

But it’s not just about core count… • Increasingly connected applications • More latency

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

The Challenges of Concurrency • A different way of thinking • Forcing the square

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

Example: Searching and Sorting IEnumerable<Race. Car. Driver> drivers =. . . ; var results

Example: Searching and Sorting IEnumerable<Race. Car. Driver> drivers =. . . ; var results = new List<Race. Car. Driver>(); foreach(var driver in drivers) { if (driver. Name == query. Name && driver. Wins. Count >= query. Win. Count) { results. Add(driver); } } results. Sort((b 1, b 2) => b 1. Age. Compare. To(b 2. Age));

Manual Parallel Solution IEnumerable<Race. Car. Driver> drivers = …; var results = new List<Race.

Manual Parallel Solution IEnumerable<Race. Car. Driver> drivers = …; var results = new List<Race. Car. Driver>(); int partitions. Count = Environment. Processor. Count; int remaining. Count = partitions. Count; var enumerator = drivers. Get. Enumerator(); try { using (var done = new Manual. Reset. Event(false)) { for(int i = 0; i < partitions. Count; i++) { Thread. Pool. Queue. User. Work. Item(delegate { while(true) { Race. Car. Driver driver; lock (enumerator) { if (!enumerator. Move. Next()) break; driver = enumerator. Current; } if (driver. Name == query. Name && driver. Wins. Count >= query. Win. Count) { lock(results) results. Add(driver); } } if (Interlocked. Decrement(ref remaining. Count) == 0) done. Set(); } done. Wait. One(); results. Sort((b 1, b 2) => b 1. Age. Compare. To(b 2. Age)); } } finally { if (enumerator is IDisposable) ((IDisposable)enumerator). Dispose(); }

PLINQ Solution IEnumerable<Race. Car. Driver> drivers =. . . ; var results = from

PLINQ Solution IEnumerable<Race. Car. Driver> drivers =. . . ; var results = from driver in drivers. As. Parallel() where driver. Name == query. Name && driver. Wins. Count >= query. Win. Count orderby driver. Age ascending select driver;

Demo PLINQ

Demo PLINQ

Visual Studio 2010 Tools, Programming Models, Runtimes Visual Studio 2010 Profiler Concurrency Visualizer Parallel

Visual Studio 2010 Tools, Programming Models, Runtimes Visual Studio 2010 Profiler Concurrency Visualizer Parallel LINQ Task Parallel Library . NET Framework 4 Thread. Pool Data Structures Parallel Debugger Tool Windows Programming Models Data Structures Tools Parallel Pattern Library Async Agents Library Visual Concurrency C++ 2010 Runtime Task Scheduler Resource Manager Operating System Threads. Windows Key: Managed Native Tooling UMS Threads

Investigations for the future…

Investigations for the future…

This is some synchronous code with. NET 4… public void Copy. Stream. To. Stream(Stream

This is some synchronous code with. NET 4… public void Copy. Stream. To. Stream(Stream source, Stream destination) { byte[] buffer = new byte[0 x 1000]; int num. Read; while ((num. Read = source. Read(buffer, 0, buffer. Length)) != 0) { destination. Write(buffer, 0, num. Read); } }

This is an expert’s asynchronous code with. NET 4… public IAsync. Result Begin. Copy.

This is an expert’s asynchronous code with. NET 4… public IAsync. Result Begin. Copy. Stream. To. Stream( Stream source, Stream destination) { var tcs = new Task. Completion. Source<object>(); byte[] buffer = new byte[0 x 1000]; Action<IAsync. Result> read. Write. Loop = null; read. Write. Loop = iar => { try { for (bool is. Read = iar == null; ; is. Read = !is. Read) { switch (is. Read) { case true: iar = source. Begin. Read(buffer, 0, buffer. Length, read. Result => { if (read. Result. Completed. Synchronously) return; read. Write. Loop(read. Result); }, null); if (!iar. Completed. Synchronously) return; break; public void Copy. Stream. To. Stream(Stream source, Stream destination) { byte[] buffer = new byte[0 x 1000]; int num. Read; while ((num. Read = source. Read(buffer, 0, buffer. Length)) != 0) { destination. Write(buffer, 0, num. Read); } } case false: int num. Read = source. End. Read(iar); if (num. Read == 0) { tcs. Try. Set. Result( null); return; } iar = destination. Begin. Write(buffer, 0, num. Read, write. Result => { if (write. Result. Completed. Synchronously) return ; destination. End. Write(write. Result); read. Write. Loop( null); }, null); if (!iar. Completed. Synchronously) return; destination. End. Write(iar); break; } } } catch (Exception e) { tcs. Try. Set. Exception(e); } }; read. Write. Loop(null); return tcs. Task; } public void End. Copy. Stream. To. Stream(IAsync. Result async. Result) { ((Task)async. Result). Wait(); }

A compiler could do the work for us… public void Copy. Stream. To. Stream(Stream

A compiler could do the work for us… public void Copy. Stream. To. Stream(Stream source, Stream destination) { byte[] buffer = new byte[0 x 1000]; int num. Read; while ((num. Read = source. Read(buffer, 0, buffer. Length)) != 0) { destination. Write(buffer, 0, num. Read); } } public Task Copy. Stream. To. Stream(Stream source, Stream destination) { byte[] buffer = new byte[0 x 1000]; int num. Read; while ((num. Read = await source. Read. Async(buffer, 0, buffer. Length)) != 0) { await destination. Write. Async(buffer, 0, num. Read); } }

Q&A

Q&A

© 2010 Microsoft Corporation. All rights reserved. Microsoft, Windows Vista and other product names

© 2010 Microsoft Corporation. All rights reserved. Microsoft, 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.