54 ms·
Ownership on its own doesn't incur any performance overhead. If what you mean is the overhead incurred by using Rc and Arc, it's just something you have to be a
by _bxg1 7y ago
Ownership on its own doesn't incur any performance overhead. If what you mean is the overhead incurred by using Rc and Arc, it's just something you have to be aware of.
- hinkley 7y ago> Ownership on its own doesn't incur any performance overhead. That means barely anything. The computational cost is paid at compile time for deciding who owns the object, but the consequences are still felt at runtime. As I understand it, no parallel thread of execution can do anything to an object while I believe I need to write to it, by any mechanism presently in Rust (or planned?). So if new computational complexity creeps into the middle of my operation then the availability of that object begins to drop like a rock. Correct? > it's just something you have to be aware of. Take any feature in any language, and this solution doesn't scale. The general case is not, "I made the code slow and I should have been aware of what I was doing." The general case is, "someone who wasn't aware of what they were doing has broken something and now we need to find it when we don't even know who did it." and, "how do we explain to people how to do better in the future instead of just scolding them?" I have been living in this very space in another language for the better part of a month, and I expect to be here again later this year. I have tools do find memory leaks, and performance bottlenecks. Is anyone thinking of analogous solutions for constrained parallelism in Rust?
- _bxg1 7y ago> constrained parallelism in Rust I'm... unsure what you mean. As far as I know Rust doesn't require any extra runtime overhead for parallelism that wouldn't be required in C++. Rust ensures you use locking mechanisms at compile time, but you still need those in C++, you just "have to be aware of it" in that case. I suppose Rust does require a value shared across threads to be reference-counted, where that might technically be optional in C++. But then you get to do manual deallocations across threads, which just sounds like a nightmare. And each thread only has to increment the counter once, so the overhead should be minuscule compared to the overhead of creating a thread in the first place. The only exception would be if you have bad lock coordination, but again, that problem is no different in Rust than it is in C++.
- steveklabnik 7y ago> I suppose Rust does require a value shared across threads to be reference-counted It does not require it; that is one of many possible strategies, depending on what you're doing.
- _bxg1 7y agoWhat are the other strategies? Aside from making it static.
- cyphar 7y agoMuch like in C, you could use several other schemes such as a Mutex (or RwLock). There are crates which implement more complicated memory management primitives -- the most obvious example being crossbeam[1]. Crossbeam even has an implementation of an epoch-based memory manager[2] which (in very loose terms) amortises the cost of reference counting each object by tracking the epochs of each thread and freeing objects once all threads have moved past the "death time" of an object. [1]: https://docs.rs/crossbeam/ https://docs.rs/crossbeam/ [2]: https://docs.rs/crossbeam/0.7.3/crossbeam/epoch/index.html https://docs.rs/crossbeam/0.7.3/crossbeam/epoch/index.html
- _bxg1 7y agoNormal mutexes in Rust still have to be paired with a reference-counting structure. Those are separate mechanisms. I don't know anything about the epoch-based manager, but it does sound interesting.
- steveklabnik 7y agoAnything that you can do in any other language. Rust doesn't force you to do anything special, only prove that what you're doing has defined behavior. No tools are forbidden.
- unlinked_dll 7y agoI'm not sure what you're getting at. In no language is it sound to mutate the same data in parallel or to read it while it is being mutated. Synchronization primitives are needed by all languages to deal with this fundamental truth. Rust just reflects this truth in the type system. That said, you can build whatever abstraction you want to deal with it. You can use immutable data structures, mutexes, lock/wait free mechanisms, whatever. Hell you can throw caution to the wind and use a raw pointer if you wanted to. That's how a lot of the higher level constructs work under the hood, they just wrap the logic required to maintain soundness under the API. That's not just a Rust thing, it's true in all languages. It's just that Rust makes it a bit easier to express soundness because of how it reflects multiple aliasing in the type system.