4 ms·
>Why do C++ programmers always refer to the overhead of "reference counting", when the overhead is not in the counting, but in the memory management Presumably
by logicchains 5y ago
>Why do C++ programmers always refer to the overhead of "reference counting", when the overhead is not in the counting, but in the memory management
Presumably they're looking at reference counting as an alternative to unique_ptr, and in that context the memory management overhead is already being paid.
- throwaway81523 5y agoUnique_ptr is basically a pointer to a refcounted object whose refcount is always 0 or 1, and therefore doesn't have to be stored in the object itself. If the unique_ptr is a non-null address than the object is alive (refcount=1), if all the unique_ptrs are null then the object is dead (so it gets freed), and C++'s fancy scope rules and move semantics statically ensure that there is at most one non-null unique_ptr to the object at any time. I have been under the impression that glibc implements both unique_ptr and shared_ptr (that's the one with arbitrary refcounts) using locks, but ok, if it's done with something like CMPXCHG that's still a heck of a lot slower than ordinary copying. As for overhead, well, if an object lives for a long time and lots of references are updated or moved around, then that itself can be expensive, besides the malloc/free costs. Copying garbage collectors by comparison are simple and fast, at the expense of making your program gobble a lot more memory, limiting the language so that the gc can know where all the pointers are, and having to stop the program during gc.
- loup-vaillant 5y agoI'd be very surprised if GCC actually used locks for unique_ptr. A unique_ptr owns the object it points to, so we know for a fact that it doesn't need to check anything before deleting it.
- throwaway81523 5y agoYou might be right about that, i.e. I probably derped up. It's been a long while since I looked at it, and the issue might only be with shared_ptr. I'm starting to remember finding out that shared_ptr was surprisingly expensive even in single threaded programs. It looks like some finer grained versions of shared_ptr (like atomic_shared_ptr) arrived recently. I haven't checked into them yet.
- BenFrantzDale 5y agoTypically unique_ptr is represented as a pointer (check sizeof). For shared_ptr, there’s an atomic refcount but no locks. Operations on the shared_ptr object itself aren’t threadsafe (you can’t have the same shared_ptr assigned by two threads at the same time without locking), just like int, but the reference count is atomic, so copies of shared_ptr can safely be shared among threads. Atomic_shared_ptr adds atomicity to the pointer itself. I believe that usually uses locks.
- spacechild1 5y ago> I have been under the impression that glibc implements both unique_ptr and shared_ptr (that's the one with arbitrary refcounts) using locks Why would unique_ptr ever need a lock? > As for overhead, well, if an object lives for a long time and lots of references are updated or moved around If performance is important you only pass a shared_ptr if the callee needs to keep it around, otherwise just pass a plain (const) reference. You can also pass a (const) reference to the shared_ptr and then the callee can decide if they actually need to keep it. Moving shared_ptr is free, because the refcount stays the same.
- jonv 5y agoWith std::shared_ptr each copy has a pointer to the ref count & there is only one ref count, atomically updated with a cmpxchg instruction. Not sure what you mean by "references are updated or moved around"? But I agree that GC has higher thruput than malloc/free as most gc allocations are a single op, at the cost of higher initial memory usage and worst-case latency. That's why "scripting" languages like python / perl use refcounting as they need to start quickly and might not run for very long, whereas java / c# programs tend to be longer running.
- jonv 5y agoNot sure what you mean here, std::unique_ptr is for when you want to auto destruct a ptr when going out of scope (ref counting limited to one) and std::shared_ptr is normal reference counting, they aren't alternatives to each other but specific things for specific situations?