On Thu, Dec 16, 2010 at 11:02 PM, Graydon Hoare <[email protected]> wrote:
> On 10-12-16 02:29 PM, Rafael Ávila de Espíndola wrote: > > Another question I found while reading the manual: >> > > Another good catch :) > > > The manual says that immutable boxes are shared and are destroyed when >> the reference count gets to zero. >> >> The problem, if I understand it correctly, is that the destructors are >> user visible, but the creation of immutable shared boxes is not in all >> cases. >> > > Indeed. There's also a further problem that in some cases we can't really > find a context in which to run a dtor (such as a dropped message), so we'd > need some kind of scavenger task. > > > When sending something over a channel the runtime can increment the >> reference copy or do an actual copy (if going to another os thread for >> example). If it copies now the destructors are run twice. >> >> We discussed some options >> >> *) Require that resources be reference counted. Really expensive, since >> the reference count would have to be atomic. >> >> *) Distinguish copyable and non-copyable mutable data. A destructor can >> then only get non copyable data and only copyable data can be sent over >> a channel (short of a move). >> >> Is the second option in line with what you had in mind? >> > > There are a few less-savoury options as well (multiple-destruction, etc.) > but I agree with your judgment of the best cases. Our current proposed (but > only weakly sketched-out) approach is the latter: distinguish the copyable > from the non-copyable. This thread brings to mind a couple of issues that I'd like to just float for your consideration. 1) Many apps build up massive immutable data structures that need to be accessed by tons of tasks (e.g. video games, my field). Copying these values would be prohibitively impractical, so any general-purpose language *must* support real sharing of immutable data somehow. Realistically, before Rust sees mainstream use we'll have >64 cores to keep busy, so anything that imposes limits on read-only data sharing between actual *cores* is going to be a big burden too. 2) I'd also argue that sharing of immutable data is the simpler and more obvious semantics. Especially when you take destructors into account. I think you should therefore have to opt-in for "copy, don't share" semantics as an optimization when you have data that ends up getting loads of incref/decref operations on them. 3) The cost of reference counting in a multi-core scenario is a concern. Rust already limits the number of reference operations using aliases, which presumably gets rid of a lot of the cost. Is Rust wedded to the idea of having accrate refcounts at all times? As far as I can tell, modern ref-counting algorithms seem to be about on par with modern GC algorithms for performance (just barely) even in the context of multithreading, but they achieve this feat through deferred ref-counting and things like that. Should Rust not do that instead? I kind of think refcounts may be the way forward in the future, because the cost of GC'ing in a ref-count system is proportional to the amount of actual garbage, rather than being proportional to the size of the heap, but it seems like the consensus on this issue in the literature is that refcounts are only performant when they're not being constantly kept up to date. Am I wrong? 4) If the cost of atomic ref counts are still too high, perhaps all allocations should be task-local unless you explicitly tag it as being shared (with task-local data not being allowed over channels)? This seems conceptually simple and impossible to mess up. You tag shared data in some special way and only for that data you pay the extra cost of more expensive ref-counting. If you forget to tag something as shared, then you'll get a compile-time error when you try to send it to another task. Note that you're still sharing data here, so you support the scenario in 1), you're just not incurring the cost for everything. I'd prefer if this wasn't necessary (i.e. if refcount operations could be statically or dynamically elided often enough that any immutable data can be sent over a channel), but you could always make the "shared" keyword a no-op in the future if that materializes. Happy holidays! Sebastian -- Sebastian Sylvan
_______________________________________________ Rust-dev mailing list [email protected] https://mail.mozilla.org/listinfo/rust-dev
