e ff ective concurrency with algebraic e ff ects
play

E ff ective Concurrency with Algebraic E ff ects Stephen Dolan 1 , - PowerPoint PPT Presentation

E ff ective Concurrency with Algebraic E ff ects Stephen Dolan 1 , Leo White 2 , KC Sivaramakrishnan 1 , Jeremy Yallop 1 , Anil Madhavapeddy 1 1 2 Concurrency Parallelism Concurrency Programming technique Overlapped execution of


  1. E ff ective Concurrency with Algebraic E ff ects Stephen Dolan 1 , Leo White 2 , KC Sivaramakrishnan 1 , Jeremy Yallop 1 , Anil Madhavapeddy 1 1 2

  2. Concurrency ≠ Parallelism • Concurrency • Programming technique • Overlapped execution of processes • Parallelism • Performance hack • Simultaneous execution of computations

  3. Concurrency ≠ Parallelism • Concurrency • Programming technique • Overlapped execution of processes • Parallelism • Performance hack • Simultaneous execution of computations Concurrency ∩ Parallelism ➔ Scalable Concurrency

  4. Concurrency ≠ Parallelism • Concurrency • Programming technique • Overlapped execution of processes • Parallelism • Performance hack • Simultaneous execution of computations Concurrency ∩ Parallelism ➔ Scalable Concurrency (Fibers) (Domains)

  5. Schedulers • Multiplexing fj bers over domain(s) Bake scheduler into the runtime system (GHC) •

  6. Schedulers • Multiplexing fj bers over domain(s) Bake scheduler into the runtime system (GHC) • • Allow programmers to describe schedulers! Parallel search —> LIFO work-stealing • Web-server —> FIFO runqueue • Data parallel —> Gang scheduling •

  7. Schedulers • Multiplexing fj bers over domain(s) Bake scheduler into the runtime system (GHC) • • Allow programmers to describe schedulers! Parallel search —> LIFO work-stealing • Web-server —> FIFO runqueue • Data parallel —> Gang scheduling • • Algebraic E ff ects and Handlers

  8. Algebraic E ff ects and Handlers • Programming and reasoning about computational e ff ects in a pure setting. • Cf. Monads • E ff ects in practice • M Pretnar, A Bauer, “E ff programming language” • http://www.e ff -lang.org/ • O Kiselyov, A Sabry, C Swords, B Foppa, “Extensible-e ff ects for Haskell” • https://hackage.haskell.org/package/extensible-e ff ects • E Brady, “E ff ects in Idris” • http://eb.host.cs.st-andrews.ac.uk/dra fu s/e ff -tutorial.pdf • O Kammar, S Lindley, N Oury , “Handlers in Action” , ICFP ’13 • dl.acm.org/citation.cfm?id=2500590

  9. Algebraic E ff ects: Example exception Foo of int let f () = 1 + (raise (Foo 3)) let r = try f () with Foo i -> i + 1 val r : int = 4

  10. Algebraic E ff ects: Example effect Foo : int -> int exception Foo of int let f () = 1 + (perform (Foo 3)) let f () = 1 + (raise (Foo 3)) let r = let r = try try f () (* spawned in a new fiber *) f () with effect (Foo i) k -> with Foo i -> i + 1 continue k (i + 1) val r : int = 4 val r : int = 5 E ff ects interface type _ eff += Foo : int -> int eff val perform : 'a eff -> 'a type ('a,'b) continuation val continue : ('a,'b) continuation -> 'a -> 'b

  11. Algebraic E ff ects: Example effect Foo : int -> int exception Foo of int let f () = 1 + (perform (Foo 3)) let f () = 1 + (raise (Foo 3)) let r = let r = try try f () (* spawned in a new fiber *) f () with effect (Foo i) k -> with Foo i -> i + 1 continue k (i + 1) val r : int = 4 val r : int = 5 E ff ects interface type _ eff += Foo : int -> int eff val perform : 'a eff -> 'a type ('a,'b) continuation val continue : ('a,'b) continuation -> 'a -> 'b

  12. Algebraic E ff ects: Example effect Foo : int -> int exception Foo of int let f () = 1 + (perform (Foo 3)) 4 let f () = 1 + (raise (Foo 3)) let r = let r = try try f () (* spawned in a new fiber *) f () with effect (Foo i) k -> with Foo i -> i + 1 continue k (i + 1) val r : int = 4 val r : int = 5 E ff ects interface type _ eff += Foo : int -> int eff val perform : 'a eff -> 'a type ('a,'b) continuation val continue : ('a,'b) continuation -> 'a -> 'b

  13. Handlers are Deep! effect Foo : int -> int let f () = (perform (Foo 3)) (* 3 + 1 *) + (perform (Foo 3)) (* 3 + 1 *) let r = try f () (* spawned in a new fiber *) with effect (Foo i) k -> (* continuation called outside try/with *) continue k (i + 1) val r : int = 8

  14. Handlers are Deep! effect Foo : int -> int let f () = (perform (Foo 3)) (* 3 + 1 *) + (perform (Foo 3)) (* 3 + 1 *) let r = try f () (* spawned in a new fiber *) with effect (Foo i) k -> (* continuation called outside try/with *) continue k (i + 1) val r : int = 8

  15. Handlers are Deep! effect Foo : int -> int let f () = (perform (Foo 3)) (* 3 + 1 *) + (perform (Foo 3)) (* 3 + 1 *) let r = try f () (* spawned in a new fiber *) with effect (Foo i) k -> (* continuation called outside try/with *) continue k (i + 1) val r : int = 8

  16. Scheduler Demo 1 [1] https://github.com/kayceesrk/ocaml15-e ff /tree/master/chameneos-redux

  17. Implementation • Fibers: Heap allocated, dynamically resized stacks • ~10s of bytes • No unnecessary closure allocation costs unlike CPS

  18. Implementation • Fibers: Heap allocated, dynamically resized stacks • ~10s of bytes • No unnecessary closure allocation costs unlike CPS • One-shot delimited continuations • Simpli fj es reasoning about resources - sockets, locks, etc.

  19. Implementation • Fibers: Heap allocated, dynamically resized stacks • ~10s of bytes • No unnecessary closure allocation costs unlike CPS • One-shot delimited continuations • Simpli fj es reasoning about resources - sockets, locks, etc. • Handlers —> Linked-list of fj bers

  20. Implementation • Fibers: Heap allocated, dynamically resized stacks • ~10s of bytes • No unnecessary closure allocation costs unlike CPS • One-shot delimited continuations • Simpli fj es reasoning about resources - sockets, locks, etc. • Handlers —> Linked-list of fj bers handle / sp continue call chain reference handler

  21. Implementation • Fibers: Heap allocated, dynamically resized stacks • ~10s of bytes • No unnecessary closure allocation costs unlike CPS • One-shot delimited continuations • Simpli fj es reasoning about resources - sockets, locks, etc. • Handlers —> Linked-list of fj bers sp handle / handle / continue continue call chain reference handler

  22. Implementation • Fibers: Heap allocated, dynamically resized stacks • ~10s of bytes • No unnecessary closure allocation costs unlike CPS • One-shot delimited continuations • Simpli fj es reasoning about resources - sockets, locks, etc. • Handlers —> Linked-list of fj bers sp handle / continue call chain perform reference handler

  23. Performance : Chameneos-Redux Lwt (bytecode) Fibers (bytecode) Concurrency Monad (bytecode) 10 7.5 Time (S) 5 2.5 0 1 2 3 4 5 6 7 8 9 10 Iterations (X100,000)

  24. Performance : Chameneos-Redux Lwt (native) Fibers (bytecode) Concurreny Monad (native) GHC (native) 1.8 1.35 Time (S) 0.9 0.45 0 1 2 3 4 5 6 7 8 9 10 Iterations (X100,000)

  25. Generator from Iterator 1 type 'a t = | Leaf | Node of 'a t * 'a * 'a t let rec iter f = function | Leaf -> () | Node (l, x, r) -> iter f l; f x; iter f r [1] https://github.com/kayceesrk/ocaml15-e ff /blob/master/generator.ml

  26. Generator from Iterator 1 type 'a t = | Leaf | Node of 'a t * 'a * 'a t let rec iter f = function | Leaf -> () | Node (l, x, r) -> iter f l; f x; iter f r (* val to_gen : 'a t -> (unit -> 'a option) *) let to_gen (type a) (t : a t) = let module M = struct effect Next : a -> unit end in let open M in let step = ref (fun () -> assert false) in let first_step () = try iter (fun x -> perform (Next x)) t; None with effect (Next v) k -> step := continue k; Some v in step := first_step; fun () -> !step () [1] https://github.com/kayceesrk/ocaml15-e ff /blob/master/generator.ml

  27. Performance : Generator Iterator Fiber Generator H/W Generator 4 3 Time (S) 2 1 0 15 16 17 18 19 20 21 22 23 24 25 Binary tree depth

  28. Concerns • Unchecked e ff ects Risks ~= exceptions • E ff ect inference in E ff 1 • [1] Matija Pretnar, “Inferring Algebraic E ff ects” , http://arxiv.org/abs/1312.2334

  29. Concerns • Unchecked e ff ects Risks ~= exceptions • E ff ect inference in E ff 1 • • Interfacing with monadic code (Lwt, Async) Use monadic re fm ection to recover direct-style code 2 • [1] Matija Pretnar, “Inferring Algebraic E ff ects” , http://arxiv.org/abs/1312.2334 [2] https://github.com/kayceesrk/ocaml15-e ff /blob/master/reify_re fm ect.ml

  30. Concerns • Unchecked e ff ects Risks ~= exceptions • E ff ect inference in E ff 1 • • Interfacing with monadic code (Lwt, Async) Use monadic re fm ection to recover direct-style code 2 • • Compilation to other backends (JS, Java?) ES6 generators, ES7 async/await • Selective-CPS transform 3 • [1] Matija Pretnar, “Inferring Algebraic E ff ects” , http://arxiv.org/abs/1312.2334 [2] https://github.com/kayceesrk/ocaml15-e ff /blob/master/reify_re fm ect.ml [3] T Rompf et al., “Implementing fj rst-class polymorphic delimited continuations by a type-directed selective CPS-transform” , ICFP ‘09

  31. Status • Bytecode only. Todo Native. • Several opportunities for optimisation • Continuations invoked at tail position • Dynamic search for e ff ect handler • Code • Multicore OCaml: https://github.com/ocamllabs/ocaml-multicore • Stand-alone e ff ects: https://github.com/kayceesrk/ocaml/tree/e ff ects • E ff ects examples: https://github.com/kayceesrk/ocaml-e ff -example

Recommend


More recommend