Future of the Threading and Garbage Collection in Ruby - Interview with Koichi Sasada
Ruby 1.9.2 is due by the end of the year - InfoQ used the release of 1.9.2 Preview 1 as an occasion to talk to Ruby 1.9.x VM maintainer Koichi Sasada about the future of the VM, Threading and the Garbage Collector.
InfoQ: At RubyConf'08 you mentioned that there were some optimizations in 1.9.x that are turned off by default, but you might turn them on in 1.9.2. What's the status of this work?
Koichi Sasada: In fact, 1.9.2 doesn't turn on optimizations. It seems to need more experience to turn on such optimizations. In short, there is no time to make experiments.
Some other trivial optimizations will be included. If I can make a time to work on it, I want to implement some other ideas such as Proc#call optimization.
InfoQ: Ruby 1.9.2 Preview 1 had the longlife GC patch applied. As I understand, a GC run for normal objects should now be faster since it ignores objects in the long lived object space (until a full GC run - which includes long lived objects - happens). Is that correct?
Koichi Sasada: Yes. Nari-san made it. Mainly, some node objects belong to generational objects. Some nodes were used as inline cache to improve VM performance. This change ignore such inline cache objects to mark on GC.
However, I re-write inline cache codes to avoid node objects. This means that inline cache code no longer use node objects. Accordingly, this GC optimization have few improvement.
InfoQ: It seems like the longlife GC patch is the first step towards a generational GC, particularly the introduction of code for handling write barriers and remembered sets. Is a generational GC possible for 1.9.2?
Koichi Sasada: No. It is limited to "uncovered" objects. This is means that the objects that are not touched from C extension libraries. If a part of code touches this object and forgets to make a write barrier, it can cause a critical bug such as causing SEGV. CRuby (Matz) may not permit such a change.
Another Japanese researcher (student) is working on auto write-barrier (WB) insertion for GC implementations that need WBs. If it succeeds, generational GC (or incremental GC, also) is no longer a dream :)
InfoQ: What are the difficulties in making a generational GC for the Ruby 1.9.x VM? I suppose moving objects might be an issue - would that create problems with native extensions?
Koichi Sasada: Problem is, as I wrote, GC techniques needs completeness. If someone forgets to add a write barrier, it should be serious problem.
In this background, another Japanese researcher proposed "mostly mark & compaction GC". This technique works as conservative, so it doesn't need completeness (of course, GC implementation should be complete. I mean that no changes are needed for extension library interface).
InfoQ: - The Unladen Swallow project aims to remove the GIL in Python. What are your plans for the GIL (or GVL in Ruby) in 1.9.2 or future versions?
Koichi Sasada: On 1.9.2 or near future, I can't release GVL (Giant VM Lock, GIL in YARV terminology).
Far future, I'm not sure. I'm also not sure that we would be happy if GVL free threads are available. In short, it makes scripting difficult.
InfoQ: Have you looked at how MacRuby solves the GIL problem?
Koichi Sasada: Great work. I want to watch the result of programmability. If every Macruby users says they're "happy", we must change our mind :)
InfoQ: Does the GVL prevent problems with native extensions?
Koichi Sasada: GVL doesn't prevent any problem :)
In fact, my doctor thesis proposes a GVL free Ruby VM, which improves performance by CPU number. On my parallel VM, a non-thread safe method (written in C) is invoked, at first, VM acquires GVL, and process such a method, and releases GVL. In my thesis, some optimization and exception safe techniques are written (unfortunately, it is written in Japanese).
On my parallel VM, VM features are thread-free, this means that parallel execution is available. However, many thread-unsafe methods remain, for example methods of String, Array and more built-in classes. This is simple (but difficult. makes buggy code easy) work to make them thread-safe (but many efforts are needed). So I can say that "it is possible, of course" from implementation side.
However, as I wrote, I'm not sure it makes us happy from language design side.
Currently, we are working on MVM (Multi-Virtual Machine) project sponsored by Sun Microsystems, Inc. This project makes it possible to invoke many VMs in a process. All VMs can run in parallel. I think it is more preferable to manipulate parallelism than thread, of course if MVM operations needs low cost enough. This cost is one of our research goals. On MVM side, we don't need to care about thread-safety, but VM communications.
This is only research project, but I want to ship off practical implementation.
In another projects, we are planning to utilize parallelism. This is under consideration, but I hope I can show such a techniques at next RubyConf.