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 @@
namespace folly {
constexpr size_t kCoreCachedSharedPtrDefaultNumSlots = 64;
/**
* This class creates core-local caches for a given shared_ptr, to
* mitigate contention when acquiring/releasing it.
......@@ -35,7 +37,7 @@ namespace folly {
*
* @author Giuseppe Ottaviano <ott@fb.com>
*/
template <class T, size_t kNumSlots = 64>
template <class T, size_t kNumSlots = kCoreCachedSharedPtrDefaultNumSlots>
class CoreCachedSharedPtr {
public:
explicit CoreCachedSharedPtr(const std::shared_ptr<T>& p = nullptr) {
......@@ -66,7 +68,7 @@ class CoreCachedSharedPtr {
std::array<std::shared_ptr<T>, kNumSlots> slots_;
};
template <class T, size_t kNumSlots = 64>
template <class T, size_t kNumSlots = kCoreCachedSharedPtrDefaultNumSlots>
class CoreCachedWeakPtr {
public:
explicit CoreCachedWeakPtr(const CoreCachedSharedPtr<T, kNumSlots>& p) {
......@@ -79,6 +81,10 @@ class CoreCachedWeakPtr {
return slots_[AccessSpreader<>::cachedCurrent(kNumSlots)];
}
std::shared_ptr<T> lock() const {
return slots_[AccessSpreader<>::cachedCurrent(kNumSlots)].lock();
}
private:
std::array<std::weak_ptr<T>, kNumSlots> slots_;
};
......@@ -95,7 +101,7 @@ class CoreCachedWeakPtr {
* get()s will never see a newer pointer on one core, and an older
* pointer on another after a subsequent thread migration.
*/
template <class T, size_t kNumSlots = 64>
template <class T, size_t kNumSlots = kCoreCachedSharedPtrDefaultNumSlots>
class AtomicCoreCachedSharedPtr {
public:
explicit AtomicCoreCachedSharedPtr(const std::shared_ptr<T>& p = nullptr) {
......@@ -105,7 +111,7 @@ class AtomicCoreCachedSharedPtr {
~AtomicCoreCachedSharedPtr() {
auto slots = slots_.load(std::memory_order_acquire);
// Delete of AtomicCoreCachedSharedPtr must be synchronized, no
// need for stlots->retire().
// need for slots->retire().
if (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