Slide 1

Slide 1 text

CONCURRENCY PATTERNS IN RUBYMOTION use the multicore Luke! 1 Samstag, 30. März 13

Slide 2

Slide 2 text

#inspect Mateus Armando MacRuby enthusiastic Rubymotion early adopter Mobile OS Obsessed Deutsche Telekom AG Who Am I? 2 Samstag, 30. März 13

Slide 3

Slide 3 text

#inspect 3 Samstag, 30. März 13

Slide 4

Slide 4 text

#inspect iOS CONCURRENCY NSOperationQueue Grand Central Dispatch (GCD) 4 Samstag, 30. März 13

Slide 5

Slide 5 text

#inspect y u no thread?... 5 Samstag, 30. März 13

Slide 6

Slide 6 text

#inspect y u no thread?... 5 Samstag, 30. März 13

Slide 7

Slide 7 text

#inspect Deadlocks 6 Samstag, 30. März 13

Slide 8

Slide 8 text

#inspect Race Conditions if has_due == true pay_my_dues() has_due = false end 7 Samstag, 30. März 13

Slide 9

Slide 9 text

#inspect Race Conditions if has_due == true pay_my_dues() has_due = false end 7 Samstag, 30. März 13

Slide 10

Slide 10 text

#inspect Race Conditions if has_due == true pay_my_dues() has_due = false end 7 Samstag, 30. März 13

Slide 11

Slide 11 text

#inspect Race Conditions if has_due == true pay_my_dues() has_due = false end 7 Samstag, 30. März 13

Slide 12

Slide 12 text

#inspect Race Conditions if has_due == true pay_my_dues() has_due = false end 7 Samstag, 30. März 13

Slide 13

Slide 13 text

#inspect Terminology Parallelism: making programs run faster by using more hardware like multiple CPU or GPU cores Concurrency: ways of structuring programs into independent activities that can communicate and synchronise with each other Parallelism ≠ Concurrency 8 Samstag, 30. März 13

Slide 14

Slide 14 text

#inspect Design Approaches for Concurrent Systems 9 Samstag, 30. März 13

Slide 15

Slide 15 text

#inspect Shared Mutability Isolated Mutability Pure Immutability 10 Samstag, 30. März 13

Slide 16

Slide 16 text

#inspect Grand Central Dispatch 11 Samstag, 30. März 13

Slide 17

Slide 17 text

#inspect Dispatch::Queue lambda {...} lambda {...} lambda {...} lambda {...} 12 Samstag, 30. März 13

Slide 18

Slide 18 text

#inspect GCD-How does it work 13 Samstag, 30. März 13

Slide 19

Slide 19 text

#inspect GCD-How does it work Task Thread 13 Samstag, 30. März 13

Slide 20

Slide 20 text

#inspect GCD-How does it work Task Task Thread 13 Samstag, 30. März 13

Slide 21

Slide 21 text

#inspect GCD-How does it work Task Task Task Thread Thread 13 Samstag, 30. März 13

Slide 22

Slide 22 text

#inspect GCD-How does it work Task Task Task Task Thread Thread Thread 13 Samstag, 30. März 13

Slide 23

Slide 23 text

#inspect GCD-How does it work Task Task Task Task Thread Thread Thread 13 Samstag, 30. März 13

Slide 24

Slide 24 text

#inspect GCD-How does it work Task Task Task Task Thread Thread Thread 13 Samstag, 30. März 13

Slide 25

Slide 25 text

#inspect Queue Task Task Task Task Execute tasks one at a time First-in, First-out (FIFO) order very lightweight (~160 bytes) can replace lock and mutexes Serial Queues 14 Samstag, 30. März 13

Slide 26

Slide 26 text

#inspect Queue Task Task Task Task Execute tasks one at a time First-in, First-out (FIFO) order very lightweight (~160 bytes) can replace lock and mutexes Serial Queues 14 Samstag, 30. März 13

Slide 27

Slide 27 text

#inspect Queue Task Task Task Task Execute tasks one at a time First-in, First-out (FIFO) order very lightweight (~160 bytes) can replace lock and mutexes Serial Queues 14 Samstag, 30. März 13

Slide 28

Slide 28 text

#inspect Serial Queues queue = Dispatch::Queue.new(“org.comp.app.task”) 15 Samstag, 30. März 13

Slide 29

Slide 29 text

#inspect Serial Queues queue = Dispatch::Queue.new(“org.comp.app.task”) def status=(new_status) @queue.sync { @status = new_status } end def status @queue.sync { return @status } end 16 Samstag, 30. März 13

Slide 30

Slide 30 text

#inspect @queue.sync do Race Conditions if has_due == true pay_my_dues() has_due = false end end 17 Samstag, 30. März 13

Slide 31

Slide 31 text

#inspect Queue Concurrent Queues Task Task Task Task ๏ may execute tasks simultaneously ๏ no guarantee for the execution order ๏ magic! 18 Samstag, 30. März 13

Slide 32

Slide 32 text

#inspect Queue Concurrent Queues Task Task Task Task ๏ may execute tasks simultaneously ๏ no guarantee for the execution order ๏ magic! 18 Samstag, 30. März 13

Slide 33

Slide 33 text

#inspect Queue Concurrent Queues Task Task Task Task ๏ may execute tasks simultaneously ๏ no guarantee for the execution order ๏ magic! 18 Samstag, 30. März 13

Slide 34

Slide 34 text

#inspect Concurrent Queues 19 Samstag, 30. März 13

Slide 35

Slide 35 text

#inspect queue = Dispatch::Queue.concurrent(:background) Concurrent Queues 19 Samstag, 30. März 13

Slide 36

Slide 36 text

#inspect queue = Dispatch::Queue.concurrent(:background) queue = Dispatch::Queue.concurrent(:low) Concurrent Queues 19 Samstag, 30. März 13

Slide 37

Slide 37 text

#inspect queue = Dispatch::Queue.concurrent(:background) queue = Dispatch::Queue.concurrent(:low) queue = Dispatch::Queue.concurrent(:default) Concurrent Queues 19 Samstag, 30. März 13

Slide 38

Slide 38 text

#inspect queue = Dispatch::Queue.concurrent(:background) queue = Dispatch::Queue.concurrent(:low) queue = Dispatch::Queue.concurrent(:default) queue = Dispatch::Queue.concurrent(:high) Concurrent Queues 19 Samstag, 30. März 13

Slide 39

Slide 39 text

#inspect queue = Dispatch::Queue.concurrent(:background) queue = Dispatch::Queue.concurrent(:low) queue = Dispatch::Queue.concurrent(:default) queue = Dispatch::Queue.concurrent(:high) Concurrent Queues 19 Samstag, 30. März 13

Slide 40

Slide 40 text

#inspect queue = Dispatch::Queue.concurrent(:background) queue = Dispatch::Queue.concurrent(:low) queue = Dispatch::Queue.concurrent(:default) queue = Dispatch::Queue.concurrent(:high) Concurrent Queues 19 Samstag, 30. März 13

Slide 41

Slide 41 text

#inspect queue = Dispatch::Queue.concurrent(“org.task”) queue = Dispatch::Queue.concurrent(:background) queue = Dispatch::Queue.concurrent(:low) queue = Dispatch::Queue.concurrent(:default) queue = Dispatch::Queue.concurrent(:high) Concurrent Queues 19 Samstag, 30. März 13

Slide 42

Slide 42 text

#inspect Concurrent Queues queue = Dispatch::Queue.concurrent('de.mateus.example') queue.async do puts "Hi There!" end queue.async do puts "Good Bye" end 20 Samstag, 30. März 13

Slide 43

Slide 43 text

#inspect Concurrent Queues 20 Samstag, 30. März 13

Slide 44

Slide 44 text

#inspect Synchronization Barriers Dispatch::Group 21 Samstag, 30. März 13

Slide 45

Slide 45 text

#inspect Barriers queue = Dispatch::Queue.concurrent('de.mateus.example') queue.async do puts "Hi There!" end queue.barrier_async do puts "Good Bye" end 22 Samstag, 30. März 13

Slide 46

Slide 46 text

#inspect Dispatch::Groups queue = Dispatch::Queue.concurrent('de.mateus.example') group = Dispatch::Group.new queue.async(group) do time = Time.now puts "Hi There! #{time}" end group.wait queue.async do puts "Good Bye" end 23 Samstag, 30. März 13

Slide 47

Slide 47 text

#inspect Dispatch.once Upon A Time - Executes a block object once and only once in your app lifetime please don’t use it for UITableView cell layout :-) at least in Rubymotion 24 Samstag, 30. März 13

Slide 48

Slide 48 text

#inspect Dispatch.once Upon A Time - Executes a block object once and only once in your app lifetime please don’t use it for UITableView cell layout :-) at least in Rubymotion 24 Samstag, 30. März 13

Slide 49

Slide 49 text

#inspect NSOperationQueue 25 Samstag, 30. März 13

Slide 50

Slide 50 text

#inspect NSOperationQueue NSOperation NSOperation NSOperation NSOperation N SO perationQ ueue 26 Samstag, 30. März 13

Slide 51

Slide 51 text

#inspect NSOperationQueue queue.addOperationWithBlock(->{ // ... do your long task }) queue = NSOperationQueue.alloc.init queue.name = “com.company.app.task” 27 Samstag, 30. März 13

Slide 52

Slide 52 text

#inspect task = NSBlockOperation.blockOperationWithBlock(->{ // ... do your long task }) queue.addOperation(task) NSOperationQueue queue = NSOperationQueue.alloc.init queue.name = “com.company.app.task” 27 Samstag, 30. März 13

Slide 53

Slide 53 text

#inspect NSOperationQueue queue = NSOperationQueue.alloc.init queue.name = “com.company.app.task” task1 = NSInvocationOperation.alloc.initWithTarget(self, selector:‘task1:’, object:”obj”) task2 = NSInvocationOperation.alloc.initWithTarget(self, selector:‘task2’, object:nil) queue.addOperations([task1, task2], waitUntilFinished:false) 27 Samstag, 30. März 13

Slide 54

Slide 54 text

#inspect NSOperation 28 Samstag, 30. März 13

Slide 55

Slide 55 text

#inspect NSOperation PRIORITIES 28 Samstag, 30. März 13

Slide 56

Slide 56 text

#inspect NSOperation DEPENDENCIES PRIORITIES 28 Samstag, 30. März 13

Slide 57

Slide 57 text

#inspect NSOperation DEPENDENCIES KVO PRIORITIES 28 Samstag, 30. März 13

Slide 58

Slide 58 text

#inspect NSOperation DEPENDENCIES KVO PRIORITIES SUSPEND/RESUME 28 Samstag, 30. März 13

Slide 59

Slide 59 text

#inspect Embrace Immutability 29 Samstag, 30. März 13

Slide 60

Slide 60 text

#inspect Embrace Immutability NSString => String # => NSString.stringWithString("") 29 Samstag, 30. März 13

Slide 61

Slide 61 text

#inspect Embrace Immutability NSString => String # => NSString.stringWithString("") NSArray => Array # => NSArray.arrayWithArray([]) 29 Samstag, 30. März 13

Slide 62

Slide 62 text

#inspect Embrace Immutability NSString => String # => NSString.stringWithString("") NSArray => Array # => NSArray.arrayWithArray([]) NSDictionary => Hash # => NSDictionary.dictionaryWithDictionary({}) 29 Samstag, 30. März 13

Slide 63

Slide 63 text

#inspect GCD Gotchas Thread safety Variable Scope Queue INCEPTION 30 Samstag, 30. März 13

Slide 64

Slide 64 text

#inspect Don’t be clever! 31 Samstag, 30. März 13

Slide 65

Slide 65 text

#inspect •Don't be afraid spawn Queues •Update UI only in the Main Queue •Dispatch::Queue.main is your Friend Working with Graphics It's A trap! 32 Samstag, 30. März 13

Slide 66

Slide 66 text

#inspect What should I use? 33 Samstag, 30. März 13

Slide 67

Slide 67 text

#inspect GCD NSOperation Work Unit Block NSOperation Can cancel? No Yes Dependencies? No Yes Concurrent execution? Yes Yes Change Queue? No Yes NSOperationQueue vs GCD 34 Samstag, 30. März 13

Slide 68

Slide 68 text

#inspect much more!!! you can get so much more from GCD. e.g: you can replace your NSTimer with Dispatch::Source 35 Samstag, 30. März 13

Slide 69

Slide 69 text

#inspect much more!!! Dispatch::Semaphore you can get so much more from GCD. e.g: you can replace your NSTimer with Dispatch::Source 35 Samstag, 30. März 13

Slide 70

Slide 70 text

#inspect much more!!! Dispatch::Semaphore Dispatch::Source you can get so much more from GCD. e.g: you can replace your NSTimer with Dispatch::Source 35 Samstag, 30. März 13

Slide 71

Slide 71 text

#inspect Create your own Abstraction 36 Samstag, 30. März 13

Slide 72

Slide 72 text

#inspect def fibonacci2(n) return n if n < 2 fib1 = fibonacci(n-1) fib2 = fibonacci(n-2) fib1 + fib2 end def fibonacci(n) return n if n < 2 fib1 = Dispatch::Promise.new { fibonacci(n-1) } fib2 = Dispatch::Promise.new { fibonacci(n-2) } fib1 + fib2 end n = 100 Benchmark.bm do |x| x.report("Parallel") { n.times do ; fibonacci(10); end } x.report("Sequential") { n.times do ; fibonacci2(10);end } end 37 Samstag, 30. März 13

Slide 73

Slide 73 text

#inspect n 0 5 100 200 300 400 500 Parallel Sequential 0,000000 0,159890 3,394287 8,568163 15,042915 29,275532 40,513081 0,000000 0,123077 4,513412 18,685437 40,315345 96,669930 174,162173 0 50 100 150 200 0 5 100 200 300 400 500 Naïve Fibonacci sequence Parallel Sequential 37 Samstag, 30. März 13

Slide 74

Slide 74 text

#inspect Question ? 38 Samstag, 30. März 13

Slide 75

Slide 75 text

#inspect http://seanlilmateus.github.com/ https://github.com/seanlilmateus/futuristic Threading Programming Guide 39 Samstag, 30. März 13

Slide 76

Slide 76 text

#inspect Things That Can Be Slow • Memory allocation • View creation • Drawing • Questionable algorithms • Questionable data structures • I/O • Blocking on information • Unnecessary work 40 Samstag, 30. März 13

Slide 77

Slide 77 text

#inspect “We should forget about small efficiencies, say abou...t 97% of the time: premature optimization is the root of all evil.” Donald Knuth ... 41 Samstag, 30. März 13

Slide 78

Slide 78 text

#inspect Queues Dispatch::Queue.new(“com.company.app.task”) Dispatch::Queue.concurrent(“com.company.app”) Dispatch::Queue.concurrent(priority=:high) Dispatch::Queue.main queue#current queue#label queue#sync queue#async queue#after queue#apply queue#dispatch_object queue#suspended? queue#suspend! queue#resume! Groups Dispatch::Group.new group#wait group#on_completion [DEPRECATED] group#notify Semaphore Dispatch::Semaphore.new(count=2) semaphore#signal semaphore#wait(time=Dispatch::TIME_NOW) Source Dispatch::Source.new(type, handle, mask, queue) Dispatch::Source.timer(delay, interval, leeway, queue) src#<< source#merge src#data src#mask src#cancel! src#cancelled? Constants Dispatch::TIME_NOW Dispatch::TIME_FOREVER 42 Samstag, 30. März 13