Holy CoW!

Posted by Rick DeNatale Wed, 16 Dec 2009 14:38:00 GMT

Last week the Phusion guys, gave a talk at Google about the implementation of Ruby Enterprise Edition, and it's now available on YouTube.

It's good stuff if you are a VM geek, like me. The cover two major topics

  1. How they made the Ruby 1.8 garbage collector Copy on Write (CoW) friendly, which allows multiple Ruby processes to share memory for unchanged objects. This greatly reduces the footprint of a typical Rails Deployment for example. They talks about a series of attempts to change the Ruby GC to move the mark bits from the objects themselves to a separate memory structure. The result is significant memory savings, a slightly slower GC, but overall faster Ruby performance because they replaced malloc with a faster allocator (from Google apparently) which more than offsets the GC performance
  2. How a contribution from the Event Machine developers improves thread context switching for Ruby 1.8's user space threads. Ruby 1.8 handles thread context switches by copying the execution stack to and from the heap, which can result in significant time being taken up by memcopy calls. Ruby Enterprise edition now has an optional feature which instead switches the base stack pointer on a thread switch. This is processor specific, and is only available right now for Intel 32 and 64 bit processors.

So if this kind of stuff interests you, I'd recommend spending the half hour or so that it takes to watch the video


The Pros and Cons of 64-Bit Architectures

Posted by Rick DeNatale Sat, 01 Nov 2008 13:17:00 GMT

My former OTI colleague Andrew “Roo” Low just wrote an interesting article about the trade-offs involved in designing a VM (and software in general) to exploit 64-bit machine architectures. Although, Roo discusses JVM implementation, he also grounds it with his experiences developing the IBM/OTI Smalltalk VM, and the lessons would be equally applicable to, say, a Ruby implementation.


Power, Responsibility and Tricksy VM Implementers

Posted by Rick DeNatale Thu, 15 Mar 2007 12:05:00 GMT

In a ruby-talk discussion of the pleasures and perils of adding to or changing core ruby classes. A practice denigrated as “monkey patching” by some, but embraced as a powerful technique, when practiced with care, by others. Someone just reported an experiment involving changing a basic core method:

 Fixnum.class_eval do
   def +(number)
     self - number
   end
 end

The result: It blew up his irb.

Ruby certainly gives a lot of power. A little, and in some cases a lot, more than most popular OO languages. Read on..

Dave Ungar, who analysed and ‘optimized’ the Berkley implementation of Smalltalk-80 for his PhD dissertation, and then went on to invent the Self language used to go around and try to torment Smalltalk implementers by asking them to add an instance variable to the Object class, something which either was disallowed or would blow up. Keep in mind that Smalltalk is a dynamic language like Ruby and such changes happen while the code is running.

Ruby survives this test. Actually, it redefines it in a way similar to the way Self did. In Smalltalk, and most OO languages, instance variables are declared in classes and the classes define a template for the memory layout of the classes instances, a given instance variable is kept in a slot at a known distance from the beginning of the object. When a class is redefined all it’s instances, and the instances of all it’s subclasses need to be re-mapped.

In Ruby, classes in general don’t actually know about their instances instance variables. Instance variables are represented as an individual hash which maps the instance variable name to its value. The instance variables only come about when an instance method is executed which defines it by mention. This means that you might well have two instances of a class, one of which has a given instance variable and one which doesn’t.

This highly dynamic nature of ruby gives it a great deal of power which is put to use by advanced Rubyists and leads to nice results like Ruby on Rails.

With great power comes great responsibility!

Tricksy VM Implementers

It might be the case in some future implementations that patching FixNum#+ might be ineffective, or intermittently effective.

For example, some Smalltalk implementations, would handle a + b under the covers as an integer add of the two object pointers and a little adjustment, followed by a quick check to see if the result were a fixnum, and only send the + message if it wasn’t. This check can be done relatively inexpensively due to the way in which references to FixNums (or SmallIntegers as Smalltalk called them) are encoded.

If a number x is in FixNum range, i.e it’s twos-complement representation will fit into a bitstring of length one less than a pointer, then it’s encoded as a ‘pointer’ with the binary value x*2+1 This means that, if the low-order bit set it’s a Fixnum otherwise it isn’t. So if we have two object pointers xp and yp, referring to the objects x and y respectively we can implement x + y as something like this pseudo-C code:

   result = xp + yp - 1;  
   if (arithmetic overflow || !(result && 1) ) {
        result = send(xp,:+,yp)
   }

Note that, if xp and yp refer to Fixnums:

   xp + yp - 1 
   = (x*2+1)+(y*2+1) - 1 
   = x*2 + y*2 + 1
   = (x+y)*2 + 1

which is the correct representation for the FixNum x+y

If we don’t get an overflow, and the low-order bit is set when we compute result, we’ve got our FixNum result and we can move on. Otherwise we need to do it the old-fashoned way.

I don’t know whether YARV already does this or might in the future. This is one of the things which VM implementers tend to look for, they ‘cheat’ and try not to get caught in the interest of performance.

Now Matz and his team might reject some of these tricks since the dynamic nature of ruby might make it harder not to be caught, but in some of these edge cases, I think that case can be made that it’s probably OK since it’s unlikely that anyone will actually redefine basic arithmetic operations on core classes such as FixNum and live to tell about it without blowing up irb or worse.