Download - Ruby memory model
![Page 1: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/1.jpg)
Ruby Memory ModelHari Krishnan
@harikrishnan83
![Page 2: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/2.jpg)
Why this talk?
![Page 3: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/3.jpg)
Memory model is not about
![Page 4: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/4.jpg)
![Page 5: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/5.jpg)
![Page 6: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/6.jpg)
A quick exercise
![Page 7: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/7.jpg)
![Page 8: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/8.jpg)
![Page 9: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/9.jpg)
Increment operation is not a single instruction
● Retrieve the current value of @count.● Increment the retrieved value by 1.● Store the incremented value back in
@count.
![Page 10: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/10.jpg)
Thread A Thread B
@count = 0Load @count = 0
Increment
Store
Load
Increment
Store
@count = 1
@count = 2
@count = 1
![Page 11: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/11.jpg)
Thread A Thread B
@count = 0Load @count = 0
Increment
Store
Load
Increment
Store@count = 1
![Page 12: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/12.jpg)
Where does reordering happen
Core 1
Cache
Core 2
Cache
Compiler
Memory
![Page 13: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/13.jpg)
What is a memory model?A memory model describes the interactions of threads through memory
and their shared use of the data
![Page 14: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/14.jpg)
Atomicity
![Page 15: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/15.jpg)
Visibility
![Page 16: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/16.jpg)
Ordering
![Page 17: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/17.jpg)
Should rubyists care about this?
Ruby is single threaded
![Page 18: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/18.jpg)
Are single threaded languages like Ruby
thread safe?
![Page 19: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/19.jpg)
Does single core imply thread safe?
![Page 20: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/20.jpg)
Concurrency is about InterleavingsThread A - Load
Thread A - Increment
Thread B - Load
Thread A - Store
Thread B - Increment
Thread B - Store
![Page 21: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/21.jpg)
Threading in Ruby
![Page 22: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/22.jpg)
How is Ruby made Single Threaded
● 1.8 - Green Threads - Global Interpreter Lock
● 1.9 - OS Threads - Global VM Lock
![Page 23: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/23.jpg)
Does GIL make you thread safe?
![Page 24: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/24.jpg)
How does GIL work?
Ruby Thread 1 Ruby Thread 2
OS Thread 1 OS 2
Timer ThreadWake up!Interrupt
![Page 25: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/25.jpg)
GIL Details
● GIL is acquired at start of Thread block and released once done
● To ensure fairness a timer thread sends an interrupt to the Thread holding GIL when other threads are waiting
● The Thread holding GIL may choose to release it based on many parameters
Refer to this excellent blog post by Jesse Storimer - http://www.jstorimer.com/blogs/workingwithcode/8085491-nobody-understands-the-gil
![Page 26: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/26.jpg)
Now do you still think it is thread safe?
![Page 27: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/27.jpg)
Never depend on GIL for Thread Safety
● GIL does not have a specification● It also ties us to MRI● Rubinius and JRuby do not have GIL
![Page 28: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/28.jpg)
Ruby does not have a documented Memory
Model
![Page 29: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/29.jpg)
Ruby right now depends on underlying Virtual Machines
● MRI is not much of an interpreter. It is a VM. - No specification for Memory Model
● JRuby - JVM - JSR 133● Rubinius - LLVM for JIT -
![Page 30: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/30.jpg)
What do we do?
![Page 31: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/31.jpg)
Start Engineering Code for Thread Safety
![Page 32: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/32.jpg)
![Page 33: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/33.jpg)
Do not leave innocent accessors lying around
![Page 34: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/34.jpg)
Methods that mutate parameters are generally
dangerous
![Page 35: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/35.jpg)
Gems to the rescue
● atomic - https://github.com/headius/ruby-atomic
● thread_safe - https://github.com/headius/thread_safe
![Page 36: Ruby memory model](https://reader033.vdocument.in/reader033/viewer/2022051819/54c44ace4a795916078b470f/html5/thumbnails/36.jpg)
Thank you!Hari Krishnan
@harikrishnan83