InfoQ

News

MacRuby Drops GIL, Gains Concurrent Threads

Posted by Werner Schuster on Jun 30, 2009

Community
Ruby
Topics
JRuby ,
Performance & Scalability ,
Runtimes
Tags
Python ,
JRuby ,
Concurrency ,
Ruby1.9 ,
MacRuby ,
Threading ,
IronRuby

Threading in Ruby has always been a troublesome issue. Ruby 1.8 implements userspace threads with performance problems and also don't make use of multiple cores.
Ruby 1.9 switched to mapping every Ruby thread to a kernel thread, which removes some of the inefficiencies in 1.8's threads - yet still only one Ruby thread can run at a time.

The reason is the Global Interpreter Lock (GIL), sometimes referred to as Global VM Lock (GVL). Every Ruby thread needs to acquire the GIL before it can run. Ruby shares this implementation detail with languages like Python (where it's been a divisive issue for nearly a decade).

In the past few years, alternative Ruby implementations have done away with the issue: JRuby and IronRuby both don't have a GIL.

Now MacRuby joins their ranks and works without a GIL, as Laurent Sansonetti explains:

All MacRuby threads are scheduled by the OS kernel and registered into the Objective-C garbage collector (which runs on its own threads) before doing anything.

While the MacRuby runtime still has shared state across all threads, it now synchronizes the access to these structures instead of only allowing one thread to be active. The details:

The Core object contains a lock that is used every time a shared data structure is accessed. Shared data structures are for example: LLVM caches, various stubs caches, BridgeSupport caches, etc.

Everything else was moved to a VM class, which is completely lock-free. A VM object is created at demand and only once for every thread that wants to access the runtime. The VM object contains data structures for the very specific thread execution, like for instance current blocks, bindings, exceptions, etc. The VM sometimes calls the Core (when defining a method for example) which acquires the Core lock, but most of the time it just runs concurrently.


The new threading system is available in MacRuby's experimental branch, which is destined to become the next MacRuby version. The branch also contains a sample (and simple) web server built with MacRuby.

Once the next stable MacRuby version is released with the new threading code, there'll be three Ruby implementations with concurrent threads, without any GIL, vs. Ruby 1.8 (userspace threads) and Ruby 1.9.x. Both JRuby and MacRuby support the Ruby 1.9.x language and libraries.

Ruby 1.9.x shares the GIL problem with Python, albeit the Unladen Swallow project promises to remove the GIL by 2010 (whether that happens and whether the provided patches actually get merged into the official Python is another matter - patches that remove the GIL have been floating around for a decade).

A final note: discussions about GILs in either Ruby or Python often bring up the argument that threads in these languages simply aren't the proper way to get concurrency. Another argument is that the GIL is only a problem with CPU bound code - I/O bound code is not a problem since the GIL is properly released, allowing other threads to run during I/O operations. With that in mind - how do you implement CPU bound code that can make use of multiple cores in Ruby? Do you take care of creating and managing multiple OS processes?

 

Ruby Memory Model by Peter Veentjer Posted Jul 1, 2009 7:47 AM
Memory overhead of multi processing by Martin Probst Posted Jul 3, 2009 2:52 AM
linux support by Roger Pack Posted Oct 7, 2009 11:36 AM
  1. Back to top

    Ruby Memory Model

    Jul 1, 2009 7:47 AM by Peter Veentjer

    So when can we expect a Ruby Memory Model? Without a Memory Model it still isn't possible to write correct behaving or performing code.

  2. Back to top

    Memory overhead of multi processing

    Jul 3, 2009 2:52 AM by Martin Probst

    It might well be that multi-threading is not the correct way to get concurrency in Ruby or Python, but if you need multi-processing you might be in trouble as well. Even a tiny Rails application instance will easily consume over 50 MB of RAM, and larger applications will require significantly more. Now if you have 100 really concurrent users, you will spend 100x50 MB = 5 GB of RAM just on the application instances (not caches!). And of course this will grow significantly if your application happens to grow.

  3. Back to top

    linux support

    Oct 7, 2009 11:36 AM by Roger Pack

    more speed sweet!
    linux support?

Educational Content

Brian Marick on 4 Challenges and 5 Guiding Values of Agile Software Development

Brian Marick takes us through a quick tour of the most important values and challenges to adopting Agile successfully (they aren't the typical challenges and values we hear in the community).

Are You a Software Architect?

The line between development and architecture is tricky. Does it exist at all? Is an ivory tower actually needed? There's a balance in the middle, but how do you move from developer to architect?

Agile – A Way of Life and Pragmatic Use of Authority

The word 'authority' sometimes produces an allergic response in hard-line agilists. Freedom and authority – both are bad if misused and both are good if used in right spirit for a noble cause.

Getting Started with Grails, Second Edition

"Getting Started with Grails" brings you up to speed on this modern web framework. Companies as varied as LinkedIn, Wired, and Taco Bell are all using Grails. Are you ready to get started as well?

Using ITIL V3 as a Foundation for SOA Governance

Those familiar with only ITIL V2 often scoff at the thought that ITIL could serve as a governance framework for SOA. With ITIL V3, the focus of the framework shifted towards service-orientation.

Adrian Colyer on AspectJ, tc Server and dm Server

SpringSource CTO Adrian Colyer discusses AspectJ, SpringSource's dm Server and tc Server products, OSGi and Scrum.

Adam Wiggins on Heroku

Heroku's Adam Wiggins talks about Rails, Background Jobs, Add-Ons, Ruby, and how Heroku manages to work around Ruby's inefficiencies using Erlang and other languages.

SOA as an Architectural Pattern: Best Practices in Software Architecture

For Grady Booch the foundation of a good architecture is patterns, SOA being just one of many patterns. In this Second Life presentation, Booch attempts to bring more clarity on what architecture is.