Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Boost Weak_Ptr: Destruction is more expensive than expected

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?

like image 608
Jake Kurzer Avatar asked Dec 17 '10 20:12

Jake Kurzer


2 Answers

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_ptrs, if you don't need to actually ever take ownership in a piece of code using a weak_ptr.

like image 93
Billy ONeal Avatar answered Sep 25 '22 21:09

Billy ONeal


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.

like image 39
Puppy Avatar answered Sep 26 '22 21:09

Puppy