3 ms·
Two more interesting ways to speed it up: - Make threads a "special" tracked API call (for example, like Rust) so that you know when something will or won't be
by nu11ptr 4y ago
Two more interesting ways to speed it up:
- Make threads a "special" tracked API call (for example, like Rust) so that you know when something will or won't be passed between threads. If it never "escapes" the thread, you can use non-atomic ref counts for the lifetime of that object (NOTE: I should add this is something I've been thinking on - I don't know how hard/feasible it is to do in practice)
- Use biased RC - don't have link to paper handy, but idea is that most multithreaded objects spend most of their life on one thread and when they are on that thread, can use non-atomic ref counts by using a separate counter. When on any other thread they use an atomic counter. When both counts hit zero, object is destroyed.
- verdagon 4y agoDefinitely! Vale, Lobster, and Cone all require explicit annotations for anything that could cross thread boundaries. Vale's design bends the rules a little bit, it blends structured concurrency with region borrow checking to allow things to temporarily escape the current thread. [0] I believe Lobster spawns a new VM per thread, and has some special abilities to share data between them, but I'm vague on the details. Cone requires an explicit permission to allow crossing thread boundaries, which I think will work pretty well. [1] I've read about biased RC before, but have been skeptical because of the branching involved. How has it worked out in practice? [0] https://verdagon.dev/blog/seamless-fearless-structured-concurrency https://verdagon.dev/blog/seamless-fearless-structured-concu... [1] https://cone.jondgoodwin.com/safety.html https://cone.jondgoodwin.com/safety.html
- nu11ptr 4y agoI've just read about it, never actually used it verbatim tbh, but just found it kinda fascinating. I wrote a somewhat modified version (I don't track local thread ID, I use Rust's type system and Send/Sync properties instead) of the algorithm for a very different purpose: I use it to allow safe moves back and forth between (non-atomic) Rc and (atomic) Arc objects. For this purpose, it is very useful. The actual Rc/Arc operations are no more expensive than regular Rust Rc/Arc (except for the last decrement on Rc - slightly more expensive) I got the idea from this person (I didn't use their algorithm though - they probably do it similar to how I do it though): https://crates.io/crates/hybrid-rc https://crates.io/crates/hybrid-rc
- rfoo 4y agoBiased GC is implemented the "nogil" Python fork. It worked okay-ish.
- elcritch 4y agoNim's ARC memory management uses the first strategy. Non-atomic refs combined with moves really speed things up! Moving data across threads requires the data be of a special type `Isolate`. It can be a bit tricky to prove to the compiler that the data is isolated, e.g. single ownership.