For whatever reason, we're seeing quite a bit of cost from destroying weak pointers. Here's the culprit code:
~weak_count() // nothrow
{
if(pi_ != 0) pi_->weak_release(); // Consumes a huge chunk of our time.
#if defined(BOOST_SP_ENABLE_DEBUG_HOOKS)
id_ = 0;
#endif
}
We aren't in debug mode, and the debug hooks aren't engaged. Weak release is consuming a truly phenomenal amount of time. Is this a known issue? Are we doing something wrong?
Boost version: 1.36
Compiler: VS2008 Compiler Suite.
We are locked into this Boost version for a variety of reasons, unfortunately, so I'm more wondering if these kind of bizarre expenditures are duplicable on newer versions, or represent the result of a known bad practice. We are only destroying on the order of 500k weak pointers, which should not produce a noticeable difference in performance from destroying a similar number of raw pointers. Certainly not a 2.5-4x increase in cost. Note that we are not deleting the objects targeted by said pointers. This expense is exclusively derived from the destruction of the pointers themselves.
What is going on here?
weak_ptr
needs something like a shared_ptr
to implement itself -- because it needs to be able to determine if the pointer still exists, it needs to have a reference counted structure somewhere that maintains it's own refcounts.
I.e., how does the weak_ptr
determine if the object still exists unless the reference count is kept available somehow for it to get to? :)
You might be able to get away with passing around raw pointers instead of weak_ptr
s, if you don't need to actually ever take ownership in a piece of code using a weak_ptr
.
Most likely, the cost comes from the atomic decrement of the reference count, which is fairly expensive compared to say, integer assignments, and could incur a cache (or to be very extreme, page) miss/fault, and being an atomic op, it also can incur things like cache line invalidations.
However, destroying a raw pointer is a no-op, so I'm not entirely sure what you were expecting from weak_ptr, but it's physically impossible for it to offer the same destruction cost if it offers any kind of destruction semantics.
Equally, it's more than possible that you're flat out overusing them. Ownership-enforcing pointers are not a silver bullet- you still have to think about who owns the object. The wide-scale use of a weak pointer suggests to me that you haven't really thought through your ownership semantics.
Finally, there's an implementation of shared_ptr and weak_ptr in MSVC 2008, in the std::tr1 namespace. You could try that.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With