Commit 9acfd80d authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook GitHub Bot

Add CoreCachedWeakPtr::lock() method, improve benchmarks

Summary:
Currently `CoreCachedWeakPtr` only exposes `get()`, which returns by value, so to lock the pointer we need to do two refcount operations, one on the weak count and one on the shared count. This is expensive.

We could return by `const&`, but I don't want to expose the internal state, as we may be able to optimize the footprint by relying on implementation details of `std::shared/weak_ptr` in the future.

Instead, expose a natural `lock()` method.

Also, improve the benchmarks:
- Add comparison with `ReadMostlySharedPtr`
- Ensure that all threads are busy for the same time, so that wall time * `numThreads` is a good approximation of overall CPU time.

Reviewed By: philippv

Differential Revision: D29762995

fbshipit-source-id: 851a82111e2726425e16d65729ec3fdd21981738
parent 6696e55c
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
namespace folly { namespace folly {
constexpr size_t kCoreCachedSharedPtrDefaultNumSlots = 64;
/** /**
* This class creates core-local caches for a given shared_ptr, to * This class creates core-local caches for a given shared_ptr, to
* mitigate contention when acquiring/releasing it. * mitigate contention when acquiring/releasing it.
...@@ -35,7 +37,7 @@ namespace folly { ...@@ -35,7 +37,7 @@ namespace folly {
* *
* @author Giuseppe Ottaviano <ott@fb.com> * @author Giuseppe Ottaviano <ott@fb.com>
*/ */
template <class T, size_t kNumSlots = 64> template <class T, size_t kNumSlots = kCoreCachedSharedPtrDefaultNumSlots>
class CoreCachedSharedPtr { class CoreCachedSharedPtr {
public: public:
explicit CoreCachedSharedPtr(const std::shared_ptr<T>& p = nullptr) { explicit CoreCachedSharedPtr(const std::shared_ptr<T>& p = nullptr) {
...@@ -66,7 +68,7 @@ class CoreCachedSharedPtr { ...@@ -66,7 +68,7 @@ class CoreCachedSharedPtr {
std::array<std::shared_ptr<T>, kNumSlots> slots_; std::array<std::shared_ptr<T>, kNumSlots> slots_;
}; };
template <class T, size_t kNumSlots = 64> template <class T, size_t kNumSlots = kCoreCachedSharedPtrDefaultNumSlots>
class CoreCachedWeakPtr { class CoreCachedWeakPtr {
public: public:
explicit CoreCachedWeakPtr(const CoreCachedSharedPtr<T, kNumSlots>& p) { explicit CoreCachedWeakPtr(const CoreCachedSharedPtr<T, kNumSlots>& p) {
...@@ -79,6 +81,10 @@ class CoreCachedWeakPtr { ...@@ -79,6 +81,10 @@ class CoreCachedWeakPtr {
return slots_[AccessSpreader<>::cachedCurrent(kNumSlots)]; return slots_[AccessSpreader<>::cachedCurrent(kNumSlots)];
} }
std::shared_ptr<T> lock() const {
return slots_[AccessSpreader<>::cachedCurrent(kNumSlots)].lock();
}
private: private:
std::array<std::weak_ptr<T>, kNumSlots> slots_; std::array<std::weak_ptr<T>, kNumSlots> slots_;
}; };
...@@ -95,7 +101,7 @@ class CoreCachedWeakPtr { ...@@ -95,7 +101,7 @@ class CoreCachedWeakPtr {
* get()s will never see a newer pointer on one core, and an older * get()s will never see a newer pointer on one core, and an older
* pointer on another after a subsequent thread migration. * pointer on another after a subsequent thread migration.
*/ */
template <class T, size_t kNumSlots = 64> template <class T, size_t kNumSlots = kCoreCachedSharedPtrDefaultNumSlots>
class AtomicCoreCachedSharedPtr { class AtomicCoreCachedSharedPtr {
public: public:
explicit AtomicCoreCachedSharedPtr(const std::shared_ptr<T>& p = nullptr) { explicit AtomicCoreCachedSharedPtr(const std::shared_ptr<T>& p = nullptr) {
...@@ -105,7 +111,7 @@ class AtomicCoreCachedSharedPtr { ...@@ -105,7 +111,7 @@ class AtomicCoreCachedSharedPtr {
~AtomicCoreCachedSharedPtr() { ~AtomicCoreCachedSharedPtr() {
auto slots = slots_.load(std::memory_order_acquire); auto slots = slots_.load(std::memory_order_acquire);
// Delete of AtomicCoreCachedSharedPtr must be synchronized, no // Delete of AtomicCoreCachedSharedPtr must be synchronized, no
// need for stlots->retire(). // need for slots->retire().
if (slots) { if (slots) {
delete slots; delete slots;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment