Now that multi-core CPUs are the norm, the challenge of taking advantage of those cores is pervasive in web development. Asynchronous software frameworks and libraries like node.js and eventmachine, and concurrency approaches of multiple processes, threads (lightweight processes), and coroutines, is something I'm trying to understand better.
Ruby Parallelism With Threads
First thing I wanted to look at was running methods in parallel in ruby using threads. The following bit of ruby launches two threads that do division twenty million times per thread.
parallel
work=["A","B"]
Launch threads
work.map! do |job| Thread.new do puts "I got #{job}" 20000000.times { 4.0/2.0 } end end
Wait for each thread to finish
work.each { |thread| thread.join }
The results of running this code on different ruby interpreters are below.
typo:code $ time /usr/local/ruby-enterprise-1.8.7-2010.01/bin/ruby parallel.rb I got A I got B
real 0m9.226s top says RSS 2340k, 1 core /typo:code
Ruby 1.8 has "green threads" which is a kind of cooperative multitasking.
typo:code $ time /usr/local/ruby/1.9.2-p136/bin/ruby parallel.rb I got BI got A
real 0m7.580s top says RSS 2648k, 1 core /typo:code
Ruby 1.9 has operating-system threads, yet only one core is in use (according to top, dual core CPU was 50% busy). Ruby's Global Interpreter Lock keeps things running sequentially.
typo:code $ time /usr/local/ruby/rbx-1.2.3/bin/ruby parallel.rb I got A I got B
real 0m5.463s top says 26,000k 1 core /typo:code
Rubinius, has I believe the same functionality and limitations as ruby 1.9 as far as threading. Look at that memory usage, wow.
typo:code $ time /usr/local/java/jruby-1.6.0/bin/jruby parallel.rb I got A I got B
real 0m7.130s top says 29,000k 2 cores /typo:code
Java is the winner here for using both cores. The same crazy memory usage. It didnt take any less time to do the same work. Another confusing result.