1、An Insiders View to Concurrency at Microsoft,Stephen Toub () Parallel Computing Platform Microsoft Corporation,Agenda,Why We (I) Care What Weve Built for Developers What Were Building for Developers,Moores Law: Alive and Well,http:/upload.wikimedia.org/wikipedia/commons/2/25/Transistor_Count_and_Moo
2、re%27s_Law_-_2008_1024.png,MS Apps Using Parallelism Example: Visual Studio,Background compilation Regex-based file search Graph layout Reference highlighting IntelliSense sorting Project build system Code analysis Unit testing ,But its not just about core count,Increasingly connected applications M
3、ore 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 Concurre
4、ncy,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 wri
5、ting software Indeterminate program behavior No longer: “A happens, then B happens, then C happens” Its 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 g
6、o 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 drivers = .; var results = new List(); foreach(var driver in drivers) if (driver.Name = queryName ,Manual Parallel Solution,IEnumera
7、ble drivers = ; var results = new List(); int partitionsCount = Environment.ProcessorCount; int remainingCount = partitionsCount; var enumerator = drivers.GetEnumerator(); try using (var done = new ManualResetEvent(false) for(int i = 0; i = queryWinCount) lock(results) results.Add(driver);if (Interl
8、ocked.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(); ,LINQ Solution,IEnumerable drivers = .; var results = from driver in driverswhere driver.Name = queryName ,
9、.AsParallel(),P,Demo,PLINQ,Visual Studio 2010 Tools, Programming Models, Runtimes,Parallel Pattern Library,Resource Manager,Task Scheduler,Task Parallel Library,Parallel LINQ,Managed,Native,Key:,Threads,Operating System,Concurrency Runtime,Programming Models,ThreadPool,Task Scheduler,Resource Manage
10、r,Data Structures,Data Structures,Tools,Tooling,Parallel Debugger Tool Windows,Profiler Concurrency Visualizer,Async Agents Library,UMS Threads,.NET Framework 4,Visual C+ 2010,Visual Studio 2010,Windows,Investigations for the future,This is some synchronous code with .NET 4,public void CopyStreamToS
11、tream(Stream source, Stream destination) byte buffer = new byte0x1000; int numRead; while (numRead = source.Read(buffer, 0, buffer.Length) != 0) destination.Write(buffer, 0, numRead); ,This is an experts asynchronous code with .NET 4,public void CopyStreamToStream(Stream source, Stream destination)
12、byte buffer = new byte0x1000; 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(); byte buffer = new byte0x1000;Action rea
13、dWriteLoop = 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)
14、 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.Comp
15、letedSynchronously) return; destination.EndWrite(iar); break; catch (Exception e) tcs.TrySetException(e); ; readWriteLoop(null);return tcs.Task; public void EndCopyStreamToStream(IAsyncResult asyncResult) (Task)asyncResult).Wait(); ,A compiler could do the work for us,public void CopyStreamToStream(
16、Stream source, Stream destination) byte buffer = new byte0x1000; 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 byte0x1000; int numRead; while (numRe
17、ad = await source.ReadAsync(buffer, 0, buffer.Length) != 0) await destination.WriteAsync(buffer, 0, numRead); ,public Task CopyStreamToStream(Stream source, Stream destination) byte buffer = new byte0x1000; int numRead; while (numRead = await source.ReadAsync(buffer, 0, buffer.Length) != 0) await destination.WriteAsync(buffer, 0, numRead); ,Q&A,