3. Why parallelize?
• Responsiveness
• “when I scroll, it’s smooth”
• Performance
• “it works fast”
• Energy saving
• “it doesn’t drain my battery”
• Convenience
• some things are parallel by nature, e.g. running two completely
separate apps
5. Threads
• What is a thread?
• It’s an abstraction made by the OS
• The CPU has no such concept
• Represents a line of calculation
• Has an ID, a stack, thread-local storage, priority, CPU registers
• Shares memory and resources within a process
• The OS scheduler runs/pauses threads
• context switching
6. Issues with threading
• Race conditions
• the result depends on the timing of the scheduler
• the behavior is non-deterministic
• can result in almost anything
• crash, wrong result, corrupted data
• So, you have to use locks/mutexes/…
• More issues: deadlocks, livelocks, starvation
• Even the best guys have trouble with these
• Security consequences, vulnerabilities
7. Know your enemy
• The compiler
• The CPU
• The memory
• Time
• Your brain
9. ARM has matured
• Apple A5 (2011)
• ARM Cortex-A9 MPCore
• 2 cores
• out-of-order execution
• speculative execution
• superscalar, pipelining (8 stages)
• NEON 128-bit SIMD
• Apple A7 (2013)
• ARMv8-A “Cyclone”
• 64-bit, 32 registers, per-core L1 cache
10. iOS has matured
• The kernel knows a lot more about the system than
the developer
• GCD
• Operation Queues
• LLVM, compiler optimizations
• GPU computations
• Accelerate.framework
12. Parallelizing tasks vs.
algorithms
• Task = a standalone unit of work
• has some inputs, gives some outputs
• “add a blur effect to these 1000 photos”
• 1 photo = 1 task (independent)
• “add a blur effect to this one 5000x5000px photo”
• 1 task = ?
• Some algorithms simply cannot be parallelized (you will not get
any significant speedup)
13. What’s thread safety?
• “Thread-safe object”
• you can safely use the object from multiple threads at the
same time
• the internal state of the object will not get corrupted and it will
behave correctly
• When you don’t know if an object is thread-safe, you have to
assume it isn’t
• How do you make your object thread-safe?
• immutability, locks, atomic reads/writes
14. Shared mutable state
• Exclusive immutable object = no problem
• Shared immutable object = no problem
• Exclusive mutable object = no problem
• Shared mutable object
• root of all evil
• you always want to minimize this
15. Global variables
• “Global variables are bad”
• Multi-threading is another very good reason not to
use global variables / global state
• Global variables are always shared
• Watch out for “hidden” global state:
• working directory, chdir()
• environment variables, putenv()
16. Thread-safety vs. iOS
• Terrible lack of proper documentation
• Most of the low-level Obj-C runtime is thread-safe
• memory management, ARC, weak references, …
• Immutable objects (NSString, NSArray, …) are thread-safe
• A few other classes are thread-safe
• Usually it’s thread-safe to call class methods
• google for “iOS thread safety”
• https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/
Conceptual/Multithreading/ThreadSafetySummary/
ThreadSafetySummary.html
17. Grand Central Dispatch
• Let’s not think about threads
• Instead, let’s think about tasks
• New concepts:
• Tasks
• Queues
• Queue-specific data
• Dispatch groups
• Dispatch sources
• Synchronization
• Semaphores, barriers
• C API (!) but has ARC and works with blocks
18. GCD queues
• Main queue
• there is just one, executed on the main thread
• Concurrent queue
• tasks run concurrently
• 4 pre-made concurrent queues with different priorities
• DISPATCH_QUEUE_PRIORITY_DEFAULT, _HIGH, _LOW, _BACKGROUND
• you can make your own
• Serial queue
• only one task at a time, in order
• you can make your own
20. GCD convenience API
• dispatch_once
• guarantees the code run only run once
• use to implement a proper and fast singleton
• dispatch_after
• execute the task at a specific time
21. It’s not threads
• GCD uses threads, but the threads are completely
managed by GCD
• You can’t assume your code will run on any specific
thread
• even two tasks from the same serial queue can run
on different threads
• Don’t use thread-local storage
• Don’t use thread priorities
23. Solutions
• Avoid shared mutable state
• communicate by message passing
• design your objects as immutable
• avoid multithreading
• Synchronization
• You must always have “a plan”
• if you can’t tell which code is supposed to run in which thread/queue, then
nobody can help you
• if you can’t tell which data can be accessed from which thread/queue, then
nobody can help you