
Programming in the Multi-Core Era Emil Sekerinski Department of Computing and Software McMaster University June 2018 40+ Years of Microprocessor Trends We have reached instruction level parallelism wall and power wall Still increasing number of transistors leads to more processor cores Communication and Synchronization in Multi-Programs Message Passing: Asynchronous: Unix pipes & filters, Erlang processes Synchronous: Go goroutines Shared Variables: Semaphores: Linux, C, Python Monitors: Java, C#, Python Transactional memory: C++, Haskell Remote procedure call: Java, Python Distributed shared memory Introduced for resource sharing, interactive programs, distribution Suitable for multi-core processors? Too many threads: slowdown due to overhead of cores switching between threads, e.g. multiplying n × n matrices ! use thread pools to reduce number of threads Threads in Programs Threads have to be explicitly created to make use of multiple cores: Too few threads: not all cores will be used ! turn independent tasks into threads [Android Guides] Threads in Programs Threads have to be explicitly created to make use of multiple cores: Too few threads: not all cores will be used ! turn independent tasks into threads Too many threads: slowdown due to overhead of cores switching between threads, e.g. multiplying n × n matrices ! use thread pools to reduce number of threads [Thread Pool in the .NET Framework] Threads in Programs Threads have to be explicitly created to make use of multiple cores: Too few threads: not all cores will be used ! turn independent tasks into threads Too many threads: slowdown due to overhead of cores switching between threads, e.g. multiplying n × n matrices ! use thread pools to reduce number of threads In addition to the static structure of modules, programs have a dynamic structure of threads. (State is distributed over global variables and thread-local variables) Smalltalk-80 Java, C#, Python, . sender caller receiver callee message method Objects should be thought of as having “independent lives”, even if the implementation is sequential How to make objects “truly concurrent”? Ada uses rendezvous, Erlang and Akka use actors Inspiration: Simula-67 and Smalltalk-80 Simula-67 objects in programs mimic objects of the “real world” objects are cooperatively scheduled ! coroutines [Birtwhistle, Dahl, Myhrhaug, Nygaard. Simula Begin, 1979.] Objects should be thought of as having “independent lives”, even if the implementation is sequential How to make objects “truly concurrent”? Ada uses rendezvous, Erlang and Akka use actors Inspiration: Simula-67 and Smalltalk-80 Simula-67 objects in programs mimic objects of the “real world” objects are cooperatively scheduled ! coroutines “Part of the problem Smalltalk-80 Java, C#, Python, . description becomes part of the solution” sender caller receiver callee message method How to make objects “truly concurrent”? Ada uses rendezvous, Erlang and Akka use actors Inspiration: Simula-67 and Smalltalk-80 Simula-67 objects in programs mimic objects of the “real world” objects are cooperatively scheduled ! coroutines “Part of the problem Smalltalk-80 Java, C#, Python, . description becomes part of the solution” sender caller receiver callee message method Objects should be thought of as having “independent lives”, even if the implementation is sequential Inspiration: Simula-67 and Smalltalk-80 Simula-67 objects in programs mimic objects of the “real world” objects are cooperatively scheduled ! coroutines “Part of the problem Smalltalk-80 Java, C#, Python, . description becomes part of the solution” sender caller receiver callee message method Objects should be thought of as having “independent lives”, even if the implementation is sequential How to make objects “truly concurrent”? Ada uses rendezvous, Erlang and Akka use actors Used for verification tools, TLA (Amazon), Event B (railways), SPIN (NASA), Microsoft Device Driver Verifier, . , for hardware description languages, but not programming languages: Widespread belief in the 80’s that guarded commands cannot be implemented efficiently Guarded Commands: A Model for Concurrency do if x1 > x2 then swap x1 and x2, x1 > x2 ! swap x1 and x2 ... x2 > x3 ! swap x2 and x4 if both x1 > x2 and x3 > x4, x3 > x4 ! swap x3 and x4 swap concurrently Guarded Commands: A Model for Concurrency do x1 > x2 ! swap x1 and x2 x2 > x3 ! swap x2 and x4 x3 > x4 ! swap x3 and x4 Used for verification tools, TLA (Amazon), Event B (railways), SPIN (NASA), Microsoft Device Driver Verifier, . , for hardware description languages, but not programming languages: Widespread belief in the 80’s that guarded commands cannot be implemented efficiently Lime: a Concurrent Object-Oriented Language class DelayedDoubler Actions execute when enabled var y: int; d: boolean All objects are concurrent init() d := true Objects synchronize through method store(u: int) method calls y := u; d := false Method blocks when guard is method retrieve(): int false d ! return y Execution is atomic up to action double method calls not d ! y := 2 * y; d := true Guards only over local fields Lime: a Concurrent Object-Oriented Language class DelayedDoubler A correct implementation of: var y: int; d: boolean init() class Doubler d := true var x: int method store(u: int) method store(u: int) y := u; d := false x := 2 * u method retrieve(): int method retrieve(): int d ! return y return x action double not d ! y := 2 * y; d := true Representative for writing to a file, sending over network, . m:5m:4 m:6m:5m m:6m m head p:6p:4p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m head p a m:5m:4m m:6m:5m m:6m m head p:6p:4p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m:5 head p a:true m:5m:4m m:6m:5m m:6m m head p:6p:4p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m:5 m head p p a a m:5m:4m m:6m:5m m:6m m head p:4p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m:5 m head p:6 p a:true a m:5m:4m m:6m:5m m:6m m head p:6p:4p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m:5 m:6 head p p a a:true m:5m:4m m:6m:5m m:6m m head p:6p:4p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m:5 m:6 m head p p p a a a m:5m:4m m:6m:5m m:6m m head p:6p p:5p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ... method add(e: int) Remove executes in O(1) time when not a and not r do if l = nil then Initialize; add 5; 6; 4 . m := e ; l := new PriorityQueue else p := e ; a := true action doAdd when a do if m < p then l.add(p) else l.add(m); m := p a := false m:5 m:6 m head p:4 p p a:true a a m:5m:4m m:6m:5m m:6m m head p:6p:4p p p p a:truea a:truea a:truea a Priority Queue class PriorityQueue Add an integer to the queue var l : PriorityQueue Remove the smallest integer ..
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages36 Page
-
File Size-