This morning I was making some Ruby code of mine thread-safe which is always fun. (I'm serious btw. I frikking love multithreaded programming!) In doing so I came across something that I found a bit surprising.
Consider the following snippet: Think it will work? Let's try...
<internal:prelude>:8:in `lock': deadlock; recursive locking (ThreadError)
 from :8:in `synchronize'
 from reentrancy.rb:5:in `block in '
 from :10:in `synchronize'
 from reentrancy.rb:4:in `'
    
Mutex is not reentrant. Wow. Ok. Let's try something else...
Let's change that Mutux into a Monitor and try again.
Alrighty, let's put on fresh underwear and give it a whirl...
Monitor is reentrant.
Nothing is free. Is there a performance penalty? Time for some benchmarks.
Here is a little benchmarking script that acquires and releases both a mutex and monitor 1 million times each:
Benchmarking results:
                 user     system      total        real
Mutex        0.400000   0.000000   0.400000 (  0.406259)
Monitor      0.870000   0.010000   0.880000 (  0.864888)
I'm curious, let's try JRuby too. We'll change bm to bmbm and fire it up.
Rehearsal ---------------------------------------------
Mutex       0.571000   0.000000   0.571000 (  0.539000)
Monitor     2.012000   0.000000   2.012000 (  2.012000)
------------------------------------ total: 2.583000sec
                user     system      total        real
Mutex       0.321000   0.000000   0.321000 (  0.321000)
Monitor     1.696000   0.000000   1.696000 (  1.696000)
> jruby --1.9 --fast reentrancy-benchmark-jruby.rb
Warmup #1/20
...
Warmup #20/20
                user     system      total        real
Mutex       0.357000   0.000000   0.357000 (  0.357000)
Monitor     0.768000   0.000000   0.768000 (  0.768000)
Mutex: No reentrancy. Fast, less than half the speed of Monitor.
Monitor: Reentrancy. Slow, little over twice as slow as Mutex.
 
Thanks for your post!
ReplyDeleteIt really helped me to understand!
No problem! Happy to hear that :)
DeleteThanks for taking the time to benchmark these!
ReplyDelete