What overhead from shared_ptr are thread safe?

std::shared_ptr guaranteed to be thread safe. I do not know which mechanism uses typical implementations to ensure this, but, of course, it must have some overhead. And this overhead will be present even if your application is single-threaded.

Is it higher? And if so, does this mean that it violates the principle of "you do not pay for what you do not use" if you do not use the guarantees of thread safety?

+6
c ++ multithreading shared-ptr
Sep 11 '14 at 6:44
source share
2 answers

If we look at the cppreference for std :: shared_ptr in the Implementation Notes section, the following is indicated:

To meet thread safety requirements, reference counts are usually incremented and decremented using std :: atomic :: fetch_add with std :: memory_order_relaxed .

It is interesting to note the actual implementation, for example the libstdc ++ document here says:

For the version of shared_ptr in libstdC ++, the compiler and library are fixed, which makes things much easier: we have atomic CAS or we don’t see, see the "Blocking policy" section below.

In the section "Selecting a blocking policy" it is said (attention):

There is one class _Sp_counted_base, which is a template parameterized on the __gnu_cxx :: _ Lock_policy enumeration. The entire family of classes is parameterized in the blocking policy, up to __shared_ptr, __weak_ptr, and __enable_shared_from_this. The actual class std :: shared_ptr inherits from __shared_ptr with a blocking policy, the parameter is automatically selected based on the stream model and the platform for which libstdC ++ is configured, so that the best available specialization will be used . This design is necessary because it will not match for shared_ptr in order to have an additional template parameter, even if it had a default value. Available Policies:

[...]

3._S_Single

This policy does not use the add_ref_lock () non-blocker without blocking. It is used when libstdc ++ is built without --enable-threads.

and further says (my attention):

For all three policies, counter increments and reductions are performed using the ext / atomicity.h functions, which detect if the program is multi-threaded. If only one thread of execution exists in then less expensive non-atomic operations are used .

So, at least in this implementation you are not paying for what you are not using.

+8
Sep 11 '14 at 6:50
source share

At least in the enhancement code on i386, boost::shared_ptr was implemented using the CAS atomic operation. This meant that although it has some overhead, it is pretty low. I expect any implementation of std::shared_ptr be similar.

In tight loops in high-performance numeric code, I found some speedups by switching to the original pointers and being very careful. But for normal code - I would not worry about that.

+4
Sep 11 '14 at 6:48
source share



All Articles