Concurrency

4,268 views

Published on

Talk about concurrency in Ruby, and comparison with a few languages

Published in: Technology, Education
0 Comments
7 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,268
On SlideShare
0
From Embeds
0
Number of Embeds
16
Actions
Shares
0
Downloads
40
Comments
0
Likes
7
Embeds 0
No embeds

No notes for slide

Concurrency

  1. 1. CONCURRENCY: RUBIES, PLURAL Elise Huard - Arrrrcamp 2010 Friday 29 October 2010
  2. 2. MULTIPROCESSOR/MULTICORE Friday 29 October 2010
  3. 3. NETWORK ON CHIP (50..96..100 CORES) Friday 29 October 2010
  4. 4. “... for the first time in history, no one is building a much faster sequential processor. If you want your programs to run significantly faster (...) you’re going to have to parallelize your program.” Hennessy and Patterson “Computer Architectures” (4th edition, 2007) Friday 29 October 2010
  5. 5. But ... forget all that (mostly) Friday 29 October 2010
  6. 6. Friday 29 October 2010
  7. 7. Friday 29 October 2010
  8. 8. language VM OS (kernel processes, other processes) Your program multicore - multiCPU Friday 29 October 2010
  9. 9. Concurrent programs != Parallel computing Friday 29 October 2010
  10. 10. 3 threads, 2 cores 1 2 3 1 1 2 3 1 2 3 core1 core2 core1 core2 Friday 29 October 2010
  11. 11. Scheduling • preemptive -> thread is told to yield (by kernel or other thread) • cooperative -> thread yields control Friday 29 October 2010
  12. 12. Processes,Threads Process 2 RAMmemory space Process 1 thread1 scheduler (OS) CPU CPU memory space thread2 t1 t2 t3 Friday 29 October 2010
  13. 13. Ruby • Process • Thread: • green threads in MRI 1.8 • native threads in MRI 1.9, Rubinius, JRuby, ... Friday 29 October 2010
  14. 14. MRI: GIL from http://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/ @igrigorik Friday 29 October 2010
  15. 15. MRI: GIL • only one thread is executed at a time • fair scheduling: timer thread! (10 μs for Linux, 10 ms for Windows) • blocking region to allow limited concurrency Friday 29 October 2010
  16. 16. Other Rubies • @evanphx working on removing the GIL on Rubinius (Hydra branch) • JRuby, IronRuby, MacRuby don’t have GIL Friday 29 October 2010
  17. 17. Multiprocess •advantage: separate state •disadvantage: overhead to spawning + context switching Friday 29 October 2010
  18. 18. Ruby: multiprocess •fork and IPC: IO.pipe, Mmap, sockets ... •DRb •Queues Friday 29 October 2010
  19. 19. def execute(&block) rd, wr = IO.pipe # to retrieve results pid = fork do rd.close result = block.call wr.write result.to_json wr.close end wr.close sorted = JSON.parse(rd.read) rd.close Process.waitpid(pid) sorted end Ruby: multiprocess Friday 29 October 2010
  20. 20. Threads Shared state: locking to avoid race conditions Mutex.synchronize do ... end ConditionVariable (semaphore) MonitorMixin, Sync_m Friday 29 October 2010
  21. 21. Ruby threads require 'thread' threads = [] account = UnsafeAccount.new mutex = Mutex.new 10.times do threads << Thread.new do mutex.synchronize do account.receive(10) end end end threads.each {|t| t.join } puts account.balance Friday 29 October 2010
  22. 22. Fibers • cooperative scheduling • coroutines • for MRI: lightweight • JRuby, Rubinius: Fiber mapped to native thread Friday 29 October 2010
  23. 23. Ruby: Coroutines require 'fiber' # coroutines ary = [] f2 = nil f1 = Fiber.new{ puts "please give your login" login = f2.transfer puts login puts "give password" pass = f2.transfer puts pass f2.transfer f2.transfer('***** no cigar *****') } f2 = Fiber.new{ f1.transfer('johndoe') f1.transfer('ultrasecret') answer = f1.transfer puts answer } f1.resume vaguely inspired by http://sheddingbikes.com/posts/1287306747.html output: please give your login johndoe give password ultrasecret ***** no cigar ***** Friday 29 October 2010
  24. 24. MVM Rubinius (2008): no parallel execution of threads in oneVM ... so let’s create oneVM per native thread vm = Rubinius::VM.spawn "blah", "-e", "puts 'hellon'" Friday 29 October 2010
  25. 25. Friday 29 October 2010
  26. 26. Shared State: will melt your brain • non-determinism • atomicity • deadlock - livelock • fairness/starvation • race conditions • locks: loss of performance Friday 29 October 2010
  27. 27. Friday 29 October 2010
  28. 28. Actor model •named actors: no shared state •asynchronous message passing (fire and forget) Friday 29 October 2010
  29. 29. CSP • member of family of Process Calculi (mathematical theory) • events, processes • synchronous (rendez-vous) message passing • named channels - dual to Actor model Friday 29 October 2010
  30. 30. Concurrency oriented languages • Erlang (Actors) • Go (CSP) • Haskell (several) • Scala (Actors) • Clojure • IO Friday 29 October 2010
  31. 31. Ideas • functional programming: side effect free - immutable data • nothing shared (advantage: distributed = local) • message passing Friday 29 October 2010
  32. 32. Erlang • Actor model:Actors, asynchronous message passing • actors = “green processes” • efficientVM (SMP enabled since R12B) • high reliability © ericsson 2007 Friday 29 October 2010
  33. 33. Erlang pid = spawn(fun() ->sort(Self, List) end) pmap_gather([]) -> []; pmap_gather([H|T]) -> receive {H, Ret} -> [Ret|pmap_gather(T)] end; Friday 29 October 2010
  34. 34. Rubinius:Actors • actors in the language: threads with inbox • VM actors to communicate between actors in differentVMs Friday 29 October 2010
  35. 35. Ruby: Revactor • erlang-like semantics: actor spawn/receive, filter • Fibers (so cooperative scheduling) • Revactor::TCP for non-blocking network access (1.9.2) (rev eventloop) Friday 29 October 2010
  36. 36. Go • Fairly low-level - fit for systems programming (close to C) • static typing • goroutines: parallel execution - sort of async lightweight thread • channels ! Friday 29 October 2010
  37. 37. Go ReplyChannel = make(chan []int) (...) request.data = less request.replyChannel = ReplyChannel go sort(&request) // async start parallel execution in sort: request.replyChannel <- sorted listener: result := <-replyChannel Friday 29 October 2010
  38. 38. Ruby: futures Lazy.rb gem (@mentalguy) puts "before first future" future1 = Lazy::Future.new { fib(40) } puts "before second future" future2 = Lazy::Future.new { fib(40) } puts "and now we're waiting for results ..." puts future1 # maybe some more code here puts future2 Friday 29 October 2010
  39. 39. Clojure functional, Lisp-like, on JVM concurrency: Software Transactional Memory System: • Refs = shared, and mutation within a transaction (atomic, consistent, isolated) - Multiversion Concurrency Control - retried if conflict • Agents: independent, asynchronous change Friday 29 October 2010
  40. 40. Clojure (import '(java.util.concurrent Executors)) (defn parallel-stm [start amount nthreads] (let [balance (ref start) pool (Executors/newFixedThreadPool nthreads) tasks (map (fn [t] (fn [] (dosync (alter balance transfer amount)))) (range nthreads))] (doseq [future (.invokeAll pool tasks)] (.get future)) (.shutdown pool) (deref balance))) Friday 29 October 2010
  41. 41. Ruby: STM • @mentalguy thought experiment • @technomancy clojure-gem Friday 29 October 2010
  42. 42. other ways to handle concurrency see http://moonbase.rydia.net/mental/ blog/programming/concurrency-five- ways.html (@mentalguy) Friday 29 October 2010
  43. 43. Kernel stuff Some of these problems have been solved before ... Friday 29 October 2010
  44. 44. FUN :) Friday 29 October 2010
  45. 45. References: http://www.delicious.com/elisehuard/concurrency Elise Huard @elise_huard http://jabberwocky.eu Friday 29 October 2010

×