41
Programming with Concurrency Programming with Concurrency #1: Concepts, Patterns, and #1: Concepts, Patterns, and Best Practices Best Practices Jan Gray Jan Gray FUN302 FUN302 Software Architect Software Architect Microsoft Corporation Microsoft Corporation

Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Embed Size (px)

Citation preview

Page 1: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Programming with Concurrency Programming with Concurrency #1: Concepts, Patterns, and Best #1: Concepts, Patterns, and Best PracticesPractices

Jan GrayJan GrayFUN302FUN302Software ArchitectSoftware ArchitectMicrosoft CorporationMicrosoft Corporation

Page 2: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

OutlineOutline

Why concurrency?Why concurrency?

Concurrency programming todayConcurrency programming today

Future concurrency modelsFuture concurrency models

Page 3: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Why Concurrency?Why Concurrency?

For responsiveness: don’t lock up!For responsiveness: don’t lock up!

For performance: parallelismFor performance: parallelism

Situation inducedSituation induced

Why Why notnot concurrency? concurrency?It brings non-determinismIt brings non-determinism

Specific knowledge and discipline Specific knowledge and discipline neededneeded

Page 4: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Concurrency for Concurrency for ResponsivenessResponsiveness

““All apps are network apps”All apps are network apps”Use web services, network files, slow disks, Use web services, network files, slow disks, ……

Latency, variance, timeouts, partial failureLatency, variance, timeouts, partial failure

How are we doing?How are we doing?User is locked out, can’t cancel, no User is locked out, can’t cancel, no repaintingrepainting

Hangs as prevalent and disruptive as Hangs as prevalent and disruptive as crashescrashes

Page 5: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Towards a Responsive AppTowards a Responsive AppDecouple UI and workDecouple UI and work

Show internal states and partial resultsShow internal states and partial results

Provide ‘cancel’Provide ‘cancel’

Exploit pre- and post-computingExploit pre- and post-computing

Define async states and behaviorsDefine async states and behaviorsSo each is a feature, not a bugSo each is a feature, not a bug

Apply same ideas to responsive Apply same ideas to responsive librarieslibraries

Document thread safe synchronous usageDocument thread safe synchronous usage

Watch out for thread issues in libraries you Watch out for thread issues in libraries you callcall

Page 6: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Building a Responsive UI Building a Responsive UI With BackgroundWorkerWith BackgroundWorker

Page 7: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Threads, UI, Thread PoolThreads, UI, Thread Pool

UI ThreadUI Thread

UI Message QueueUI Message Queue(and Pumping)(and Pumping)

Thread PoolThread Pool

Thread PoolThread PoolThreadThread

RunWorkerAsyncRunWorkerAsync

ProgressChangedProgressChanged

RunWorkerCompletedRunWorkerCompleted

DoW

ork

DoW

ork

Page 8: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Concurrency for Concurrency for PerformancePerformanceWelcome to the multi-core era!Welcome to the multi-core era!

Processors don’t get way faster –Processors don’t get way faster –You just get more and more slow You just get more and more slow onesones

log transistors/dielog transistors/dielog CPU clock freqlog CPU clock freq

2003200319751975

10,00010,0001 MHz1 MHz

100 M100 M3 GHz3 GHz

20152015

5 B5 B

<10 GHz<10 GHz

<10%/y<10%/y

>30%/y>30%/y

!!

Page 9: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

20052005→2010 →2010 Microprocessor Microprocessor TrendsTrends90→65→45 nm lithography advances90→65→45 nm lithography advances

Twice, twice again as many (faster) Twice, twice again as many (faster) transistorstransistors““Slower” wires + maxed out thermal Slower” wires + maxed out thermal envelopeenvelope→ slower CPU frequency scaling→ slower CPU frequency scalingSame freq + more cores + more cache Same freq + more cores + more cache RAMRAM→ ~same cache/core and compute/core→ ~same cache/core and compute/core

Architecture advancesArchitecture advances(Hardware) multithreading(Hardware) multithreadingOptimizing for throughput, powerOptimizing for throughput, powerSystem-on-a-Chip integration: System-on-a-Chip integration: interconnects, shared caches, I/O and interconnects, shared caches, I/O and DRAM controllersDRAM controllers

Proliferation of PC multiprocessor Proliferation of PC multiprocessor topologiestopologies

Page 10: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Change and OpportunityChange and OpportunityWindows Vista era: 1-4 cores, 1-8 hw Windows Vista era: 1-4 cores, 1-8 hw threads?threads?

Soon cheap servers with Soon cheap servers with many many corescores

Great opportunities for new killer appsGreat opportunities for new killer apps

Chip vendors can and will provide as Chip vendors can and will provide as many cores and threads as developers many cores and threads as developers can harnesscan harness

If you come, they will build itIf you come, they will build it

Page 11: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Concurrency for Concurrency for Performance?Performance?Many of today’s apps are not CPU Many of today’s apps are not CPU

boundboundGreater use of concurrency for Greater use of concurrency for responsivenessresponsiveness enables increased CPU enables increased CPU utilizationutilization

IfIf CPU bound, consider parallelism CPU bound, consider parallelismTune your algorithms and dataTune your algorithms and data first!first!

Let perf goals and measurements guide Let perf goals and measurements guide youyouEvery ~2 years, twice as many cores...Every ~2 years, twice as many cores...(See also)(See also)

Improving .NET App. Perf. and ScalabilityImproving .NET App. Perf. and Scalability::http://msdn.microsoft.com/library/en-ushttp://msdn.microsoft.com/library/en-us /dnpag/html/ /dnpag/html/scalenetscalenet.asp.aspRico Mariani’s blogRico Mariani’s blog: : http://blogs.msdn.com/http://blogs.msdn.com/ricomricom

Page 12: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

OutlineOutline

Why concurrency?Why concurrency?

Concurrency programming todayConcurrency programming today

Future concurrency modelsFuture concurrency models

Page 13: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Some Concurrency Some Concurrency Programming ModelsProgramming Models

Server per-client work-unit Server per-client work-unit parallelismparallelismImplicit data parallelism: SQL, Implicit data parallelism: SQL, Direct3DDirect3DInduced concurrency: UI events, CLR Induced concurrency: UI events, CLR finalizers, web servicesfinalizers, web servicesLoop parallelism: OpenMPLoop parallelism: OpenMPMessage passing: MPI, CMessage passing: MPI, Cωω, CCR, CCRImplicit parallelism in functional Implicit parallelism in functional languageslanguagesThreads, shared memory, and Threads, shared memory, and lockslocks

Page 14: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Threads, Shared Memory, Threads, Shared Memory, and Locks: Concepts (1 of 2)and Locks: Concepts (1 of 2)

““Simultaneous” multiple threads of Simultaneous” multiple threads of controlcontrol

Shared memory changes under youShared memory changes under youShared: global data, static fields, heap Shared: global data, static fields, heap objects objects

Private: PC, registers, locals, stack, Private: PC, registers, locals, stack, unshared heap objects, thread local unshared heap objects, thread local storagestorage

The three isolation techniquesThe three isolation techniquesConfinement: sharing less of your stateConfinement: sharing less of your state

Immutability: sharing read-only stateImmutability: sharing read-only state

Synchronization: using Synchronization: using lockslocks to serialize to serialize access to writeable shared stateaccess to writeable shared state

Thread 1: Thread 2:... ...lock(a) { ... ... lock(a) { ... ...

aalocklock

11

22Thread 1 Thread 1 lockslocks aaThread 2Thread 2 blocks blocks untiluntilaa is unlocked is unlocked

Page 15: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Concepts (2 of 2)Concepts (2 of 2)Invariants: logical correctness Invariants: logical correctness propertiesproperties

Safety vs. Liveness vs. EfficiencySafety vs. Liveness vs. EfficiencySafetySafety: program is “correct”: invariants : program is “correct”: invariants holdhold

Race conditions → violated invariantsRace conditions → violated invariants→ hard bugs→ hard bugs

LivenessLiveness: program makes progress: no : program makes progress: no deadlocksdeadlocks

EfficiencyEfficiency: as parallel as possible: as parallel as possible

Waiting (for another thread to do Waiting (for another thread to do something)something)

Consumer awaits producerConsumer awaits producer

Manager awaits workersManager awaits workers

Thread 1: Thread 2:lock(a) { ... ... lock(b) { ... ... lock(b) { ... ... lock(a) { ... ... } ... ... } ... ...} ... }

aalocklock

bblocklock

11

22

Deadlock!Deadlock!

Page 16: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Concepts Recap:Concepts Recap:Sequential vs. Sequential vs. MultithreadedMultithreadedSequential Programs Multithreaded

Programs

Memory is stable Memory is in flux(unless private, read-only,or protected by lock)

No locks needed Locks essential

Invariants hold on entry/exit to data structure methods

Invariants must hold when data’s lock not held

OK to access two data structures

If structures related, locks for both must be held

Deadlock can’t happen Deadlock is possible if multiple unordered locks

Page 17: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Key Managed Threading Key Managed Threading APIsAPIsThreading: creating concurrent Threading: creating concurrent

activitiesactivitiesThreadPool.QueueUserWorkItem(ThreadPool.QueueUserWorkItem(delegatedelegate))new Threadnew Thread(threadstart),(threadstart), Thread.Start(), Thread.Start(), Thread.Join()Thread.Join()

Locking: synchronizing (serializing) Locking: synchronizing (serializing) your shared memory accessesyour shared memory accesses

locklock((objobj) ) statement statement [[SyncLockSyncLock in VB] in VB]Monitor.Monitor.EnterEnter((objobj););try { try { statementstatement; }; }finally { Monitor.finally { Monitor.ExitExit((objobj); }); }

Waiting: scheduling workWaiting: scheduling workMonitor.Wait(Monitor.Wait(objobj))Monitor.Pulse(Monitor.Pulse(objobj), Monitor.PulseAll(), Monitor.PulseAll(objobj))

Page 18: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

class MyList<T> { T[] items; int n;

void Add(T item) { items[n] = item; n++; } …}

class MyList<T> { T[] items; int n;

void Add(T item) { lock (this) { items[n] = item; n++; } } …}

Page 19: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

Lock over entire Lock over entire invariantinvariant

class MyList<T> { T[] items; int n;

void Add(T t) { lock(this) items[n] = t; lock(this) n++; } …}

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null

void Add(T t) { lock(this) { items[n] = t; n++; } } …}

Page 20: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

Lock over entire Lock over entire invariantinvariant

Use private lock Use private lock objectsobjects

And don’t lock on And don’t lock on Types or stringsTypes or strings

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null

void Add(T t) { lock(this) { items[n] = t; n++; } } …}

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null object lk = new object();

void Add(T t) { lock(lk) { items[n] = t; n++; } } …}

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null … static void ResetStats() { lock(typeof(MyList<T>)){ … } } …}

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null static object slk = new object(); … static void ResetStats() { lock(slk){ … } } …}

Page 21: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

Lock over entire Lock over entire invariantinvariant

Use private lock Use private lock objectsobjects

And don’t lock on And don’t lock on Types or stringsTypes or strings

Don’t call others’ Don’t call others’ code while you hold code while you hold lockslocks

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null object lk = new object();

void Add(T t) { lock(lk) { items[n] = t; n++; Listener.Notify(this); } } …}

class MyList<T> { T[] items; int n; // invariant: n is count // of valid items in list // and items[n] == null object lk = new object();

void Add(T t) { lock(lk) { items[n] = t; n++; } Listener.Notify(this); } …}

Page 22: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

Lock over entire Lock over entire invariantinvariant

Use private lock Use private lock objectsobjects

And don’t lock on And don’t lock on Types or stringsTypes or strings

Don’t call others’ Don’t call others’ code while you hold code while you hold lockslocks

Use appropriate Use appropriate lock granularitieslock granularities

class MyService { static object lk_all = …;

static void StaticDo() { lock(lk_all) { … } } void Do1() { lock(lk_all) { … } } void Do2() { lock(lk_all) { … } }}

class MyService { static object lk_all = …; object lk_inst = …;

static void StaticDo() { lock(lk_all) { … } } void Do1() { lock(lk_inst) { … } } void Do2() { lock(lk_inst) { … } }}

class MyService { static object lk_all = …; object lk_inst = …; object lk_op2 = …;

static void StaticDo() { lock(lk_all) { … } } void Do1() { lock(lk_inst) { … } } void Do2() { lock(lk_op2) { … } }}

Page 23: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

Lock over entire Lock over entire invariantinvariant

Use private lock Use private lock objectsobjects

And don’t lock on And don’t lock on Types or stringsTypes or strings

Don’t call others’ Don’t call others’ code while you hold code while you hold lockslocks

Use appropriate Use appropriate lock granularitieslock granularities

Order locks to Order locks to avoid deadlockavoid deadlock

class MyService { A a; // lock: lkA B b; // lock: lkB // order! lock(a) < lock(b) … void DoAB() { lock(a) lock(b) { a.Do(); b.Do(); } } void DoBA() { lock(a) lock(b) { b.Do(); a.Do(); } }}

class MyService { A a; B b; …

void DoAB() { lock(a) lock(b) { a.Do(); b.Do(); } } void DoBA() { lock(b) lock(a) { b.Do(); a.Do(); } }}

Page 24: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Locking Rules and Best Locking Rules and Best PracticesPractices

Lock over all Lock over all writeable shared statewriteable shared state

And always use the And always use the same lock for the given same lock for the given statestate

Lock over entire Lock over entire invariantinvariant

Use private lock Use private lock objectsobjects

And don’t lock on And don’t lock on Types or stringsTypes or strings

Don’t call others’ Don’t call others’ code while you hold code while you hold lockslocks

Use appropriate Use appropriate lock granularitieslock granularities

Order locks to Order locks to avoid deadlockavoid deadlock

Page 25: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

public class Channel<T> { T t; bool full; object mon = new object();

public T Get() { … lock (mon) { while (!full) Monitor.Wait(mon); …

public void Put(T t) { lock (mon) { … full = true; Monitor.PulseAll(mon); …

while (!full) lock (mon) { Monitor.Wait(mon); …

lock (mon) { if (!full) Monitor.Wait(mon); …

lock (mon) { while (!full) Monitor.Wait(mon); …

Waiting Rules and Best Waiting Rules and Best PracticesPracticesWait exampleWait example

Use only the one true Use only the one true wait patternwait pattern

Test and retest Test and retest condition while condition while holding lockholding lock

Complete exampleComplete exampleCorrect (?) but could Correct (?) but could be more efficientbe more efficient

Pulse vs. PulseAllPulse vs. PulseAll

public class Channel<T> { T t; bool full; object mon = new object();

public T Get() { T t = default(T); lock (mon) { while (!full) Monitor.Wait(mon); t = this.t; full = false; Monitor.PulseAll(mon); } return t; } public void Put(T t) { lock (mon) { while (full) Monitor.Wait(mon); this.t = t; full = true; Monitor.PulseAll(mon); } }}

Page 26: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Concurrency for Concurrency for PerformancePerformance

Page 27: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation
Page 28: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Parallel PrimesCount Parallel PrimesCount ThreadingThreadingU

I Th

read

UI Th

read

UI Message QueueUI Message Queue(and Pumping)(and Pumping)

Thread PoolThread Pool

Thread Pool ThreadsThread Pool ThreadsRunWorkerAsyncRunWorkerAsync

QUWIQUWI

while

… M

onito

r.Wait

while

… M

onito

r.Wait

RunWorkerCompleted

RunWorkerCompleted

Page 29: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Other Concurrency Other Concurrency FacilitiesFacilities

WaitHandle,WaitHandle,AutoResetEvent,AutoResetEvent,ManualResetEvenManualResetEvent,t,Mutex, Mutex, SemaphoreSemaphore

Async pattern, IOAsync pattern, IO

Maybe laterMaybe laterInterlocked.*Interlocked.*

ReaderWriterLockReaderWriterLock

Thread.InterruptThread.Interrupt

Async delegatesAsync delegates

Waiting on events is Waiting on events is more flexible than more flexible than Monitor.WaitMonitor.Wait

Prefer ThreadPool overPrefer ThreadPool overexplicit thread mgmtexplicit thread mgmt

Prefer ThreadPool.QUWI Prefer ThreadPool.QUWI over async delegatesover async delegates

Prefer polling for Prefer polling for cancel over cancel over Thread.InterruptThread.Interrupt

Page 30: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Possible Future Concurrency Possible Future Concurrency ModelsModels

Page 31: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Looking Looking Way Way AheadAheadIn Search of Better Concurrency ModelsIn Search of Better Concurrency Models

Remember “old SW runs faster on new Remember “old SW runs faster on new PCs and faster still on next year’s PCs”?PCs and faster still on next year’s PCs”?Scaling up server apps Scaling up server apps – client apps? – client apps?Vision: what we did for memory Vision: what we did for memory managementmanagement(CLR v1), we aim to do for concurrency:(CLR v1), we aim to do for concurrency:

Using our evolved languages, libs, tools, Using our evolved languages, libs, tools, you’ll build & ship an app with lots of latent you’ll build & ship an app with lots of latent parallelismparallelismOn new HW, automatically apply extra HW On new HW, automatically apply extra HW resources to realize more latent parallelismresources to realize more latent parallelismMore tasks, more loops run in parallelMore tasks, more loops run in parallelAll without exposing latent races or All without exposing latent races or deadlocksdeadlocks

Page 32: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Looking AheadLooking AheadWorks and Explorations In ProgressWorks and Explorations In Progress

Developer ToolsDeveloper ToolsOpenMP (Visual C++ in Visual Studio 2005, OpenMP (Visual C++ in Visual Studio 2005, MSDN)MSDN)

Concur (see TLN309)Concur (see TLN309)

““Language Integrated Query” (see TLN306)Language Integrated Query” (see TLN306)

Microsoft Research (see FUN323)Microsoft Research (see FUN323)RaceTrack: detecting inconsistent lock usageRaceTrack: detecting inconsistent lock usage

Spec#: disciplined lockingSpec#: disciplined locking

CCωω: synchronization using chords (message : synchronization using chords (message joins)joins)

Software transactional memorySoftware transactional memory

Parallelism in HaskellParallelism in Haskell

Microsoft IncubationMicrosoft IncubationConcurrency and Coordination RuntimeConcurrency and Coordination Runtime

Page 33: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Looking AheadLooking AheadExample: Concurrency & Coordination Example: Concurrency & Coordination RuntimeRuntimeA local message passing library for A local message passing library for

highly concurrent teams of taskshighly concurrent teams of tasksTasks invoke other tasks by posting Tasks invoke other tasks by posting messages on their portsmessages on their portsTasks Tasks activateactivate message handlers to message handlers to accept (streams of) (joined) messagesaccept (streams of) (joined) messagesNo locks – you only send messages, No locks – you only send messages, and activate and execute handlersand activate and execute handlersStatus: incubation project; see Status: incubation project; see http://channel9.msdn.com/wiki/default.http://channel9.msdn.com/wiki/default.aspx/Channel9.ConcurrencyRuntimeaspx/Channel9.ConcurrencyRuntime

class WorkItem { public int m, n; // count primes in interval [m..n] public Port<int> pResult; // post the count here

public WorkItem(int m, int n, Port<int> pResult) { this.m = m; this.n = n; this.pResult = pResult; }}

void CountPrimes(int N, int chunkSize, Port<int> pTotal) { Port<WorkItem> pWork = new Port<WorkItem>(); Port<int> pResults = new Port<int>(); // post work item messages for (int i = 1; i <= N; i += chunkSize) pWork.post(new WorkItem(i, i+chunkSize-1, pResults));

// handle a stream of arbitrarily many work item messages activate( !pWork.with(delegate(WorkItem item) { // <count primes in interval [item.m .. item.n]> item.pResult.post(count); }));

// await (join over) all result messages then add them up activate( joinvariable<int>(pResults, N/chunkSize, delegate(int[] counts) { int total = 0; foreach (int count in counts) total += count; pTotal.post(total); }));}

Page 34: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Looking AheadLooking AheadExample: Software Transactional Example: Software Transactional MemoryMemoryShared memory + locks = Shared memory + locks = extra extra

complexitycomplexitySimple mistakes Simple mistakes → data races, deadlocks→ data races, deadlocks

Concurrent-componentConcurrent-component composition issues composition issues

STM: STM: atomic { a(); b(); c(); … }You think “I’m the only code on the You think “I’m the only code on the machine!”machine!”

STM observes your reads and writesSTM observes your reads and writes,, does does concurrency control, abort/retry for youconcurrency control, abort/retry for you

Automatic error clean up (back out) too!Automatic error clean up (back out) too!

Status: ‘research’Status: ‘research’

Page 35: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Conclusions / Call to Conclusions / Call to ActionAction

Concurrency is increasingly important Concurrency is increasingly important for responsiveness and parallelismfor responsiveness and parallelism

Multi-core era brings change and Multi-core era brings change and opportunityopportunity

Our platforms, languages, libraries, and Our platforms, languages, libraries, and tools will evolve to simplify tools will evolve to simplify concurrencyconcurrency

You now know key concepts and rules You now know key concepts and rules for programming with shared memory for programming with shared memory and locksand locks

TRY IT!TRY IT!

Page 36: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

ResourcesResources

Herb Sutter, Herb Sutter, The Free Lunch Is OverThe Free Lunch Is Overhttp://www.gotw.ca/publications/concurrency-http://www.gotw.ca/publications/concurrency-ddj.htmddj.htm

Vance Morrison, Vance Morrison, What Every Dev Must Know What Every Dev Must Know About Multithreaded AppsAbout Multithreaded Apps, MSDN, Aug 05, , MSDN, Aug 05, Oct 05Oct 05http://msdn.microsoft.com/msdnmag/issues/05/08/Concuhttp://msdn.microsoft.com/msdnmag/issues/05/08/Concurrency/rrency/

MSDN Library / .NET Framework Advanced MSDN Library / .NET Framework Advanced Development / Development / Asynchronous CallsAsynchronous Calls docs docsAndrew Birrell, Andrew Birrell, Programming With Threads in Programming With Threads in C#C#http://research.microsoft.com/~birrell/papers/ThreadsCShhttp://research.microsoft.com/~birrell/papers/ThreadsCSharp.pdfarp.pdf

Doug Lea, Doug Lea, Concurrent Programming In JavaConcurrent Programming In JavaIntel Platform 2015Intel Platform 2015

Page 37: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

CommunityCommunityRelated PDC talksRelated PDC talks

FUN405FUN405: : Programming with Concurrency #2 Programming with Concurrency #2 (4:15p today room 403AB)(4:15p today room 403AB)FUNL04: FUNL04: Tips & Tricks: Writing Performant Tips & Tricks: Writing Performant Managed Code Managed Code (Wed 12:30p lunch)(Wed 12:30p lunch)TLN306: TLN306: The .NET Language Integrated Query The .NET Language Integrated Query Framework Framework (Wed 1:45p)(Wed 1:45p)FUN323FUN323: : Microsoft Research: Future Possibilities Microsoft Research: Future Possibilities in Concurrencyin Concurrency (Fri 8:30a) (Fri 8:30a)TLN309TLN309: : C++: Future Directions in Language C++: Future Directions in Language InnovationInnovation (Fri 10:30a) (Fri 10:30a)DAT301: DAT301: High Perf. Computing with the Windows High Perf. Computing with the Windows Server Compute Cluster SolutionServer Compute Cluster Solution (Tue 1:00p (at (Tue 1:00p (at home on DVD))home on DVD))

Ask the ExpertsAsk the ExpertsFundamentals/Performance/Concurrency (Thu Fundamentals/Performance/Concurrency (Thu 6:30p)6:30p)

Questions?Questions? (Evals (Evals please!)please!)

Page 38: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

© 2005 Microsoft Corporation. All rights reserved.This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.

Page 39: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Appendix: Parallel PrimesCount source Appendix: Parallel PrimesCount source (1)(1)// NB: quick hack by Jan Gray, no warranties of fitness, etc.// NB: quick hack by Jan Gray, no warranties of fitness, etc.// For illustrative purposes only.// For illustrative purposes only.

using System;using System;using System.ComponentModel;using System.ComponentModel;using System.Diagnostics;using System.Diagnostics;using System.Windows.Forms;using System.Windows.Forms;using System.Threading;using System.Threading;

namespace Primes {namespace Primes { public partial class CountPrimesForm : Form {public partial class CountPrimesForm : Form { private Stopwatch stopwatch = new Stopwatch();private Stopwatch stopwatch = new Stopwatch(); public CountPrimesForm() {public CountPrimesForm() { InitializeComponent();InitializeComponent(); }} private void button1_Click(object sender, EventArgs e) {private void button1_Click(object sender, EventArgs e) { result.Text = "working...";result.Text = "working..."; startButton.Enabled = false;startButton.Enabled = false; cancelButton.Enabled = true;cancelButton.Enabled = true; Update();Update();

stopwatch.Reset();stopwatch.Reset(); stopwatch.Start();stopwatch.Start(); bg.RunWorkerAsync((long)n.Value);bg.RunWorkerAsync((long)n.Value); }} private void bg_DoWork(object sender, DoWorkEventArgs e) {private void bg_DoWork(object sender, DoWorkEventArgs e) { long n = (long)e.Argument;long n = (long)e.Argument; long count = (new Primes()).CountPrimes(n, bg);long count = (new Primes()).CountPrimes(n, bg); if (count == -1)if (count == -1) e.Result = "cancelled";e.Result = "cancelled"; elseelse e.Result = String.Format("{0} primes <= {1}", count, n);e.Result = String.Format("{0} primes <= {1}", count, n); }} private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {private void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { result.Text = String.Format("{0} (after {1} s)", e.Result, stopwatch.ElapsedMilliseconds/1000.0);result.Text = String.Format("{0} (after {1} s)", e.Result, stopwatch.ElapsedMilliseconds/1000.0); progressBar1.Value = 0;progressBar1.Value = 0; startButton.Enabled = true;startButton.Enabled = true; cancelButton.Enabled = false;cancelButton.Enabled = false; }} private void cancelButton_Click(object sender, EventArgs e) {private void cancelButton_Click(object sender, EventArgs e) { bg.CancelAsync();bg.CancelAsync(); }} private void bg_ProgressChanged(object sender, ProgressChangedEventArgs e) {private void bg_ProgressChanged(object sender, ProgressChangedEventArgs e) { progressBar1.Value = e.ProgressPercentage;progressBar1.Value = e.ProgressPercentage; }} }}}}

Page 40: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Appendix: Parallel PrimesCount source Appendix: Parallel PrimesCount source (2)(2)// NB: quick hack by Jan Gray, no warranties of fitness, etc.// NB: quick hack by Jan Gray, no warranties of fitness, etc.// For illustrative purposes only.// For illustrative purposes only.

using System;using System;using System.Collections.Generic;using System.Collections.Generic;using System.ComponentModel;using System.ComponentModel;using System.Threading;using System.Threading;

namespace Primes {namespace Primes { public class Primes {public class Primes {/*!*/ // condition variable 'mon' -- pulsed whenever completedTasks changes/*!*/ // condition variable 'mon' -- pulsed whenever completedTasks changes private object mon = new object();private object mon = new object(); // shared read-only (after initialization)// shared read-only (after initialization) private List<long> lowPrimes = new List<long>();private List<long> lowPrimes = new List<long>(); // shared writable, guarded by lock(mon)// shared writable, guarded by lock(mon) private long totalCount;private long totalCount; private int completedTasks;private int completedTasks;

public long CountPrimes(long n, BackgroundWorker bg) {public long CountPrimes(long n, BackgroundWorker bg) { // build shared read-only low primes table// build shared read-only low primes table CountPrimesInRange(2, (int)Math.Sqrt(n) + 1, bg, true);CountPrimesInRange(2, (int)Math.Sqrt(n) + 1, bg, true);

// divvy up primes counting work into tasks of 'chunkSize' integers// divvy up primes counting work into tasks of 'chunkSize' integers const int chunkSize = 1000;const int chunkSize = 1000; int tasks = 0;int tasks = 0;

/*!*/ lock (mon) {/*!*/ lock (mon) { totalCount = 0;totalCount = 0; completedTasks = 0;completedTasks = 0; }}

// issue primes finding work items// issue primes finding work items for (long i = 2; i <= n; i += chunkSize) {for (long i = 2; i <= n; i += chunkSize) { ++tasks;++tasks;/*!*/ ThreadPool.QueueUserWorkItem(Callback,/*!*/ ThreadPool.QueueUserWorkItem(Callback, new Args(i, Math.Min(i + chunkSize - 1, n), bg));new Args(i, Math.Min(i + chunkSize - 1, n), bg)); }}

// wait until all tasks are completed// wait until all tasks are completed/*!*/ lock (mon) {/*!*/ lock (mon) { while (completedTasks < tasks && !bg.CancellationPending) {while (completedTasks < tasks && !bg.CancellationPending) { bg.ReportProgress(100 * completedTasks / tasks);bg.ReportProgress(100 * completedTasks / tasks); Monitor.Wait(mon);Monitor.Wait(mon); }} }}

return bg.CancellationPending ? -1 : totalCount;return bg.CancellationPending ? -1 : totalCount; }} // threadpool callback arguments// threadpool callback arguments class Args {class Args { public long m, n;public long m, n; public BackgroundWorker bg;public BackgroundWorker bg; public Args(long m, long n, BackgroundWorker bg) {public Args(long m, long n, BackgroundWorker bg) { this.m = m;this.m = m; this.n = n;this.n = n; this.bg = bg;this.bg = bg; }} }} private void Callback(object obj) {private void Callback(object obj) { Args args = (Args)obj;Args args = (Args)obj; long rangeCount = CountPrimesInRange(args.m, args.n, args.bg, false);long rangeCount = CountPrimesInRange(args.m, args.n, args.bg, false);

/*!*/ lock (mon) {/*!*/ lock (mon) { totalCount += rangeCount;totalCount += rangeCount; ++completedTasks;++completedTasks; Monitor.Pulse(mon);Monitor.Pulse(mon); }} }} private long CountPrimesInRange(long m, long n, BackgroundWorker bg, bool addToLowPrimes) {private long CountPrimesInRange(long m, long n, BackgroundWorker bg, bool addToLowPrimes) { long count = 0;long count = 0; for (long i = m; i <= n; i++) {for (long i = m; i <= n; i++) { if (bg.CancellationPending)if (bg.CancellationPending) return -1;return -1; foreach (long p in lowPrimes) {foreach (long p in lowPrimes) { if (p * p > i)if (p * p > i) goto prime;goto prime; if (i % p == 0)if (i % p == 0) goto composite;goto composite; }}prime: ++count;prime: ++count; if (addToLowPrimes)if (addToLowPrimes) lowPrimes.Add(i);lowPrimes.Add(i);composite: ;composite: ; }} return count;return count; }} }}}}

Page 41: Programming with Concurrency #1: Concepts, Patterns, and Best Practices Jan Gray FUN302 Software Architect Microsoft Corporation

Threading Concepts (3 of Threading Concepts (3 of 2)2)Memory Consistency ModelsMemory Consistency Models

Caches, optimizations can cause Caches, optimizations can cause observed loads and stores to “reorder” in observed loads and stores to “reorder” in other threadsother threads

““This makes my brain hurt!”This makes my brain hurt!”

A non-issue if A non-issue if allall your writeable shared your writeable shared memory accesses are under locksmemory accesses are under locks

Resist temptation to go “lock free”!Resist temptation to go “lock free”!

(See also)(See also)FUN405: FUN405: Programming with Concurrency Programming with Concurrency #2 #2 (4:15p today room 403AB)(4:15p today room 403AB)

Vance Morrison, MSDN, Oct 05Vance Morrison, MSDN, Oct 05