10 ms·
Proposal of a new concurrency model for Ruby 3 [pdf]
- zeckalpha 10y agoHow does this compare to the ongoing efforts to remove the GIL in Python? It looks like the Ruby GVL would stay, but be scoped to a Guild, rather than a Process?
- pmontra 10y agoYes, it becomes a guild global lock.
- artellectual 10y agoAnyone correct me if I'm wrong here. Seems like a guild is just a subprocess with its own resources. And you copy objects over as needed. And when the guild is done it will get garbage collected. Like other objects.
- Someone 10y agoI think I would consider implementing it as 1:1 threading where every thread=guild runs its own set of green threads. That likely would be faster than having OS threads in each guild that use PS locks to prevent running >1 of them concurrently.
- _ko1 10y agoCRuby/MRI supports C-extension which can use TLS (thread-local-storage). So that each Ruby threads runs on one OS thread.
- the_mitsuhiko 10y ago> Seems like a guild is just a subprocess with its own resources. In an ideal world the guild is the interpreter state which would be very far from processes. How far down you can go there largely depends on what promises the API made to C extensions and other things in the past.
- Roboprog 10y agoThe Guild concept feels much like a mix of actors and messaging from Erlang and Go. Not as restrictive as Erlang, but not as permissive as Go. (there was a nod to Elixir/Erlang in the slides)
- _ko1 10y agoYes. Actually, I think Go is some kind of multi-thraeding (goroutine is only a useful mechanism on the "threads" and can't help to avoid multi-threads difficulties (but this design helps to reduce difficulties)).
- Roboprog 10y agoI would like to thank the team behind this proposal, very much, by the way. I have not tinkered with Ruby in a few years, but this looks like a major breakthrough.
- _ko1 10y agoLike sub-process, but share many things like bytecodes (ISeq in MRI context), class and module objects (and method tables) and so on. Also we can share immutable objects (deeply frozen objects) like threads.
- viraptor 10y agoAre there any ongoing efforts? There's pypy trying to use STM, but don't know of any other attempts - definitely not in cpython.
- zeckalpha 10y agoYes. There was an excellent talk at Pycon 2016, entitled the GILectomy: https://www.youtube.com/watch?v=P3AyI_u66Bw https://www.youtube.com/watch?v=P3AyI_u66Bw
- the_mitsuhiko 10y agoThe proposal in the PDF looks like what I tried to implement many years ago in Python but I gave up in agony due to some stupid design decisions in Python (in particular non heap types and how type checks in the c level work). Python's attempts to remove the GIL are not going anywhere really.
- masterleep 10y agoHow would you use this to parallelize Rails requests? I guess you would need a pool of guilds, each with its own set of controllers, etc. Since the requests would not be in the "main" guild, it might be painful to call into gems.
- artellectual 10y agoI guess you could boot up a pool of guilds in your process or better yet get generated on demand as requests are coming in, to process the request, and kill the guild off when the process is done since the request object shouldn't be shared. It all really depends on how much overhead there is to create and destroy guilds. If it's easy then ideally you could start 100s of guilds or 1000s should your hardware allow it. I see guilds as a subprocess with its own isolated resources.
- pmontra 10y agoIdeally guilds could be equivalent to lightweight processes at application level (not OS), much like in Erlang. Then they could be scheduled to run concurrently using OS threads (multiple guilds per thread) and take advantage of multiple cores. That's part of BEAM, the Erlang VM. I think it's going to take a while.
- pmontra 10y agoTl;dr The goal is to keep compatibility with Ruby 2. It introduces the concept of guilds and channels to send objects between guilds. The bullet points below are quoted from a couple of slides, the other text is mine: * Guild has at least one thread (and a thread has at least one fiber) * Threads in different guilds can run in parallel * Threads in a same guild can not run in parallel because of GVL (or GGL: Giant Guild Lock) A guild can't access the objects of other guilds. About channels: * We have Guild::Channel to communicate each other * 2 communication methods 1. Copy 2. Transfer membership or Move in short Copy is a deep copy and the object is duplicated into the destination guild. A transfer removes an object from a guild and makes it available to another. There are also immutable objects that are available to all guilds. An obvious example are numbers, which are objects in Ruby, booleans and symbols. I think that other objects are frozen with https://ruby-doc.org/core-2.3.1/Object.html#method-i-freeze https://ruby-doc.org/core-2.3.1/Object.html#method-i-freeze They already did some encouraging benchmarks.
- azr79 10y agosounds reasonable to me
- bad_user 10y agoSo guilds are effectively OS-managed processes?
- pmontra 10y agoFrom the slides I got the idea that there is only one OS process with guilds and possibly threads within guilds. But it could be that the language doesn't care and that's an implementation detail. We'll see.
- audunw 10y agoNo, the heap is shared among guilds. See the last slide. Moving data between guilds is cheap because data does not have to be copied. Referencing frozen (immutable) data is cheap to. It seems it will track ownership of objects to make sure guilds don't access other guilds data. But it doesn't seem that it uses OS-level data protection.
- jph 10y agoThe key points IMHO: 1. This Ruby 3 proposal says that Ruby 2 compatibility is mission critical, therefore this proposal rejects concurrency solutions from other languages (e.g. Erlang) and concepts (e.g. functions) and data structures (e.g. immutable collections). 2 Instead the proposal is to create a fast copy-on-write with rules to "deep freeze" some kinds of objects and primitives into an immutable sharable state.
- nateberkopec 10y ago> This Ruby 3 proposal says that Ruby 2 compatibility is mission critical Matz has been very public about his fear of a "Python 3" situation occurring in the Ruby community.
- awj 10y agoAnd rightly so, I should think. Given the presence of languages like Elixir and Go, creating a situation where you are breaking people's code to introduce multicore programming systems is a pretty bad idea. I can easily see how people might (rightly or wrongly) say "Ruby 3 broke my code, I'm rewriting in Go".
- _ko1 10y agoCould you link to http://www.atdot.net/~ko1/activities/2016_rubykaigi.pdf http://www.atdot.net/~ko1/activities/2016_rubykaigi.pdf ? current one is on temporary file space (will be removed soon).
- tenderlove 10y agoApparently I can't change the link. I'm sorry! :-(
- lake99 10y agoThe mods can do it. I once left a comment about changing the link. They saw it and changed it on their own. I don't know how to notify them though.
- yxhuvud 10y agoI'm reasonably certain they are notified if the article is flagged, but I suppose it may not be the correct way of doing it.
- nitrogen 10y agoAIUI flagging the article can also affect its ranking or kill it entirely, so it's probably not the best way.
- scott_s 10y agoThe mods will tend to see questions in threads on the main page, but the way to contact them directly is hn@ycombinator.com. (From the guidelines, https://news.ycombinator.com/newsguidelines.html https://news.ycombinator.com/newsguidelines.html)
- DanWaterworth 10y agoThis is interesting. It doesn't mention GC, but since frozen objects can be shared between guilds, I assume the GC remains global. Perhaps this will trigger interest in immutable datastructures in ruby.
- _ko1 10y agoQuoted from slides: > GC/Heap > * Share it. Do stop the world parallel marking- and lazy concurrent sweeping. > * Synchronize only at page acquire timing. No any synchronization at creation time.
- DanWaterworth 10y agoI stand corrected.
- claudiug 10y agodo we have any date from this new way of doing concurrency in ruby?
- deleted 10y ago[deleted]
- readittwice 10y agoHmm, I am wondering how moving ownership would work in a GC'ed system. You could have arbitrarily many references to the moved object (or subobjects). The slides say that an exception is thrown if an object of a different guild is accessed, but doesn't that mean that Ruby needs to check the guild at every object access? Transfering ownership would probably also mean that Ruby not only needs to move one object but probably all subobjects recursively as well. I assume here that "moving" just means updating the guild field for each object. Is this really feasible or wouldn't just copying the object be faster... I don't know of any system with gc that uses moving to transfer mutable objects between threads. Do such systems exist? Are there better ways of implementing this?
- chrisseaton 10y ago> The slides say that an exception is thrown if an object of a different guild is accessed, but doesn't that mean that Ruby needs to check the guild at every object access? Ruby is already checking the class of the object on every access. You could combine the guild and the class into a tuple and compare against that instead, so it adds no extra overhead. There is a paper at OOPSLA this year on doing just that http://2016.splashcon.org/event/splash-2016-oopsla-efficient-and-thread-safe-objects-for-dynamically-typed-languages http://2016.splashcon.org/event/splash-2016-oopsla-efficient...
- VeejayRampay 10y agoHi Chris, you've mentioned that you didn't like discussing design choices made or attempted to be made in Ruby in the past, preferring to focus on the technical side of implementing the language, so no worries if you don't want to weigh in on this, but how do you feel about this proposal in general, in terms of feasibility and upside/downside of the technique described?
- chrisseaton 10y agoYes I think it looks like a very sensible way forward. It will let the VM share and optimise a lot behind the scenes but provide the illusion of clean isolation between the parallel guilds.
- porges 10y agoI{HEART}COM
- gamesbrainiac 10y agoAny idea where the video of the talk is?
- steveklabnik 10y agoRuby Kaigi has just started, so I'm guessing it will be a while.
- _ko1 10y agoYes.
- deleted 10y ago[deleted]
- transfire 10y agoHope thy improve the syntax, it looks horrid -- code in strings and all.
- _ko1 10y agoBecause of current limitation. We'll improve it.
- DougBarth 10y agoIf I'm reading this proposal correctly, locks will still be needed within multithreaded guilds to guard mutations against complex object graphs. Here's my reasoning. Since the GVL is insufficient to guard against data races on Ruby 2, under the guild system, locks would be needed to guard against concurrency issues if multiple threads are present. It would seem like the intention would be to replace usages of Thread with Guild to avoid the concurrency issues inherent with threaded code. Will there be API support to create a Guild that only allows a single thread?
- nateberkopec 10y ago> If I'm reading this proposal correctly, locks will still be needed within multithreaded guilds to guard mutations against complex object graphs. That is correct. You'll still need to use locks if doing multi-threading inside of Guilds. It looks like Guilds can have 1 to X threads.
- dragonwriter 10y ago> locks will still be needed within multithreaded guilds It seems to me that is the intent; that is, any Ruby code that exists now is single-guild Ruby 3 code -- if its multithreaded, it needs locks, for the same reason it does now. > It would seem like the intention would be to replace usages of Thread with Guild to avoid the concurrency issues inherent with threaded code I think that'll be a common use case, though running what amount to multiple "legacy" Ruby 2 multithreaded systems in separate Guilds in the same Ruby 3 process seems also to be an intended supported use case. > Will there be API support to create a Guild that only allows a single thread? It certainly sounds like a good idea.
- kent1 10y agoI worked on a similar proposal during my PhD thesis. It is formalized for a Java-like language and implemented in the Jikes RVM. We also carried a proof of isolation using Coq. https://tel.archives-ouvertes.fr/tel-00933072 https://tel.archives-ouvertes.fr/tel-00933072
- mattnewton 10y agoThat looks really useful. If you have time, please chime in on the proposal!
- kent1 10y agoThe ownership check is requiered for each access to an object. However it is straightforward to understand that successive checks of the same object can be optimized out if the object has not been passed to another owner. In this thesis I describe dynamic and static analyses to remove the unecessary checks.
- sciurus 10y agoThis reminds me in some ways of Eric Snow's (rejected, afaik) proposal to extend "subinterpreters" to allow parallelism in Python. https://lwn.net/Articles/650489/ https://lwn.net/Articles/650489/
- ivoras 10y agoOk, "guilds"? Is the principle behind this so much different than everything done before that it requires repurposing a completely new word? On par with That's "crates". Gives the impression some people just want to be remembered as inventing names.
- dragonwriter 10y ago> "guilds"? Is the principle behind this so much different than everything done before that it requires repurposing a completely new word? Pretty much. I mean, if there is a standard name for a thing between a process and a thread that is not a thread group, I haven't heard it.
- jellymann 10y agoThe PDF appears to have been removed. I'm getting a "Not Found" page.