Issue #12020 has been updated by Charles Nutter.


I have had a quick read through comments on this issue, and I have a few responses. Sorry for my late arrival...I had not realized there was this much discussion happening :-)

I think my position on this boils down to three things:

1. Ruby currently has a shared-memory, thread-based concurrency system.
2. There's no memory model documented for that system.
3. There needs to be such a model.

Anything outside these discussion points seems irrelevant to me. Yes, Ruby 3 may have some new concurrency model, some day. Not even matz knows what it will be. That *possible* future can't be used as a point against fixing specification gaps in the *current* model. And waiting until 2020 (most recent estimate for Ruby 3 that I've heard) to formally publish a memory model for Ruby seems unreasonable.

Ruby has needed this memory model formality since we started working on JRuby ten years ago. We had to unilaterally declare a memory model for JRuby in order to reconcile Ruby's lack of a memory model with Java's explicit and strict model.

We don't want to be the only Ruby 2.x implementation that has a memory model, especially if it may conflict with the realities of CRuby. Therefore we need to do something today.

As I understand it, the model described by this document does not force many (or any?) changes on CRuby. CRuby would be able to meet all or most of the requirements of the memory model by having the global lock, but other implementations without a lock would be able to run code in parallel without breaking user expectations.

Having an explicit memory model would actually *help* people avoid shared-memory problems. Right now, without a memory model, we can't safely build the sorts of concurrency primitives people need. If we can get some formality in Ruby *today* we can build Actors, Futures, Channels, concurrent lock-free collections, and more...using nothing but Ruby. That's what we want...to empower Ruby the language to solve the concurrency problems of today's Rubyists.

As an example...

I have done development on the JVM for the past 20 years. I have only had to write explicit threaded code since I started working on JRuby. Java users don't Thread.new...they spin up executors, wait on futures, message actors. All the utilities and patterns discussed here are supported by Java and the JDK classes low level, shared-memory, threading primitives backed by a strong memory model. If we had such a memory model for Ruby, we'd be able to provide the same features *efficiently* and make it *less likely* that people would be using Thread directly.

I think it's valuable to be able to implement Ruby's future concurrency models in Ruby, isn't it? That won't happen without a memory model.

A few specific responses:

ko1:

> However it will be error prone if shared-everything model is allowed.

Shared-everything is how Ruby works today. We want a solution for today's Ruby. (Petr said something similar above.) And to repeat my last point...shared-everything would be a whole lot easier for Ruby folks to deal with if they had the kinds of memory guarantees and data structures and concurrency APIs that Java folks take for granted. We're making things MUCH MUCH WORSE by not having a model in place.

> Shared everything model (thread-model)
> * Pros. we can share everything easily.
> * Cons. requires fine-grain consistency control for some data structures to guarantee memory model.

I've already pointed out that this is what we have today, without any formality. But again, having a memory model means we could build those better abstractions *in Ruby* so people don't have to worry about fine-grained consistency themselves.

> I believe performance is not a matter.

It is when it is. People leave CRuby (or Ruby the language) when it becomes important to use up all the cores or run straight-line code really fast. I think we want a language that makes programmers happy *both* when programming *and* when running that code, don't we? Programmer happiness is about more than just having a nice language...it's also about having that language's runtime meet your needs.

> Basically, (at least on MRI) I against this proposal because it is too difficult to understand and to implement.

We want to help you understand this proposal, and I want to help implement any changes that are needed! :-)

> I believe we should introduce memory consistency model on more higher-level abstraction, like Go language does.

That sounds great, but until it happens we need to fix this gaping hole in Ruby's documentation/specification. We have threads today. We can't build better abstractions above threads without a memory model. But we *can* build better abstractions once a model is in place, making it *less* likely people will stumble over threads.

Eric Wong:

> To give us the most freedom in the future, I prefer we have as few guarantees as practical about consistency.

This is probably the most dangerous way to go of all. Threads are here, they're exposed to Ruby, and they need a solution now. People already rely on Ruby's implicit memory model (whether they realize it or not), and they turn to JRuby's explicit memory model when they run on many cores. We're mostly asking that the implicit become explicit.

This doesn't limit any freedom in the future either...especially when people are talking about even more drastic solutions like removing Thread. Fixing Ruby 2.x threading and memory model does not mean Ruby 3 can't change.

> I strongly disagree with volatility in method and constant tables. Any programs defining methods/constants in parallel threads and expecting them to be up-to-date deserve all the problems they get.

I agree to a point...and that point is autoload. With the presence of autoload in Ruby, there will *always* be concurrent modifications of classes happening. I have proposed previously that all requires should be using the SAME lock, so you can't have code running in one load that's affected by code running in another load. I have also proposed that reopening a class should not publish its changes until the class is closed again. Both solutions help the problem, neither was accepted.

Autoload is the problem here, not users loading code in parallel by themselves.

Eric also says:

> The inline, global (, and perhaps in the future: thread-specific) caches will all become expensive if we need to ensure read-after-write consistency by checking for changes on methods and constants made by other threads.

JRuby does this now, and runs most code much faster than in CRuby. Cache coherency for VM-level structures does not mean you have to sacrifice performance.

...

Sorry my responses are out of order from the comments...and I apologize again for not getting involved earlier. I believe with all my heart we need to make this move for today's Ruby (and today's Rubyists), regardless of what tomorrow's Ruby may or may not do. Please help us!

----------------------------------------
Feature #12020: Documenting Ruby memory model
https://bugs.ruby-lang.org/issues/12020#change-59213

* Author: Petr Chalupa
* Status: Assigned
* Priority: Normal
* Assignee: Koichi Sasada
----------------------------------------
Defining a memory model for a language is necessary to be able to reason about a program behavior in a concurrent or parallel environment. 

There was a document created describing a Ruby memory model for concurrent-ruby gem, which fits several Ruby language implementations. It was necessary to be able to build lower-level unifying layer that enables creation of concurrency abstractions. They can be implemented only once against the layer, which ensures that it runs on all Ruby implementations.

The Ruby MRI implementation has stronger undocumented guaranties because of GIL semantics than the memory model, but the few relaxations from MRIs behavior allow other implementations to fit the model as well and to improve performance.

This issue proposes to document the Ruby memory model. The above mentioned memory model document which was created for concurrent-ruby can be used as a starting point: https://docs.google.com/document/d/1pVzU8w_QF44YzUCCab990Q_WZOdhpKolCIHaiXG-sPw/edit#. Please comment in the document or here.

The aggregating issue of this effort can be found [here](https://bugs.ruby-lang.org/issues/12019).



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>