Concurrency: Rubies, plural
Elise Huard
Moore’s Law finally hit in 2002. Multiprocessor response, plus non-uniform memory access. Important to be aware of concurrency.
But … forget all that (mostly)
Concurrent programming != parallel computing
Thread level paralleism vs instruction level
Not orderly more like a stream of cars on a busy road that soldiers in lock step.
Scheduling
- Preemtive → told to yield
- Cooperative → thread yields control
Threads are the unit of execution. Process container/memory space of one or more threads. Context of thread.
Ruby
Process
- 1.8 green
- 1.9 Native threads MRI 1.9, Rubinius
MRI: GIL
Global Interpreter Lock
Only one thread executed at a time, scheduling of threads fair. Main and time. Blocking region to allow limited concurrency. (Blocking IO driver)
Other Rubies
Parallel quicksort
Easy to parallelise, put each tree in its own thread.
Multiprocess
Separate state
disadvantege overhead to cpawinign & context switching
Ruby: for and IPC: IO.pipe Mmap
DRb
Fibers – not parallel. Cooperative scheduling, coroutines – passing between fibers at same point.
MVM
Rubinius – VM per native thread. Looks out of date now and not supported?
Shared state will melt your brain
- non-determinism
- atomicity
- deadlock
- livelock
- fairness/starvation
- race conditions
Actor model
named actors: no shared state – asynchronous message passing fire & forget
CSP
Communication Sequential Processing
- Process calculi
- Events, processes
- Synchronous message passing (rendez-vous)
- named channels – dual to Actor model
Languages
- Erlang
- Clojure
- Go (CSP)
- Haskell (several)
- Scala (Actors)
- …
Ideas
- Functional programming – no side effects, immutable data
- Nothing shared
- message passing
Erlang
- Actor model: Actors, asynch message passing
- actors = “green processes:
- efficient VM (SMP since R12B)
- high reliability
Rubinius
- Actions in the language, threds with inbox
- VM actors (not working at the moment)
Ruby: Revactor
- elrang-like senatics: actor spawn/receive, filter
- Fibers (so coop scheduling)
- Revactor::TCP for non-blocking
Go
- Fairly low-level fit for systems programming
- static typing
- goroutines: parallel execution – sort of async lightweight thread
- channels (sync named)
Clojure
Functional, lisp-like
Concurrency, Sottware Transactional Memory system
- Vars = variable state is thread isolated
- Refs = shared, and mitation within a transaction (atominc. consistent, isolated) – Multiversion concurrency control
Ruby: STM
- @mentalguy
Kernel stuff
Some of these problems have been solved before.
http://www.delicious.com/elisehuard/concurrency
http://github.com/elisehuard/rubyandrails-2010
Rubinius
Dirkjan Bussink, Nedap
1.1 is out! Bug fixes, block inlining, new debugger API and included debugger as a reference, improved GIL (used ideas from Python 3.2)
2006 Ruby interpreter in Ruby, is it possible to write more of Ruby in Ruby?
2010 1.0 release
2 virtual machines (3 if you count the 1st VM in Ruby) new VM in C++ better fits Ruby’s model from C++
1.75 garbage collectors
3 bytecode compilers (based on MRI parser)
1 Ruby core library
2 primitives systems – call into VM to do work for you
2 JIT compilers
Rubyspec
Create a reference for Rubinius and create in Ruby.
Memory
Compacting garbage garbage collector
Generational – long lived objects out the way not scan every object every time
Fast workers die young
Instance variable packing, keeps track of instance variables used in compilation
JIT
InlineCache – simple technique, remember where method was found. But need to invalidate caches if class has been changed. Method calling much faster than MRI. Counts how many times you call the method, and looks at chain of calls. JIT using LLVM – intermediate representation (IR) assembly language for LLVM.
Debugging
Debugger.here – shows backtrace, disassemble into bytecode
The awesome backtrace, proper alignment, different colours for what kind of code
Profiling
Measuring is knowing and guessing is often wrong. Runs twice, warm up to get inlining and optimisations. Profiler graphs too so that you can trace why things take time when they don’t in isolation.
Contributing
One patch accepted == commit access
Rather have a policy of being very open.
rbx my_awesome_code.rb
Future
- 1.9 support new Hash syntax, encodings
- Windows support
- Hydra GIL removed
Audio Synthesizers
Jeff Rose, Sam X
Clojure. Serge modular synth
Modules/patch cables/no save button
Software synths like Circle – can’t get into the guts and rearrange things. Visial programming analogues. Finally found SuperCollider – own language based on Smalltalk. Getting into clojure, connect it to back end audio engine of SuperCollider …
Generate music / hack. Representing a waveform as arrays of numbers and manipulating them. Software – sound card DAC takes sample values and makes smooth waveform. Voltate corresponds to position of an electromagnet.
Crash course in Clojure …
Overtone – library around SuperCollider API
Compile synthesiser in terms of DSP units and function you can call to trigger it.
Live coding session followed. It was ok for a while.