Re: Atomic caching of smart pointers

Liste des GroupesRevenir à cl c++ 
Sujet : Re: Atomic caching of smart pointers
De : eesnimi (at) *nospam* osa.pri.ee (Paavo Helde)
Groupes : comp.lang.c++
Date : 16. Sep 2024, 23:31:02
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vca82m$32puo$1@dont-email.me>
References : 1 2
User-Agent : Mozilla Thunderbird
On 15.09.2024 23:13, Chris M. Thomasson wrote:
On 9/15/2024 11:54 AM, Paavo Helde wrote:
>
I am thinking of developing some lock-free data structures for better scaling on multi-core hardware and avoiding potential deadlocks. In particular, I have got a lot of classes which are mostly immutable after construction, except for some cached data members which are calculated on demand only, then stored in the object for later use.
>
Caching single numeric values is easy. However, some cached data is large and accessed via a std::shared_ptr type refcounted smartpointers. Updating such a smartpointer in a thread-shared object is a bit more tricky. There is a std::atomic<std::shared_ptr> in C+ +20, but I wonder if I can do a bit better by providing my own implementation which uses CAS on a single pointer (instead of DCAS with additional data fields or other trickery).
>
This is assuming that
>
a) the cached value will not change any more after assigned, and will stay intact until the containing object destruction;
>
b) it's ok if multiple threads calculate the value at the same time; the first one stored will be the one which gets used.
>
My current prototype code is as follows (Ptr<T> is similar to std::shared_ptr<T>, but is using an internal atomic refcounter; using an internal counter allows me to generate additional smartpointers from a raw pointer).
>
template<typename T>
class CachedAtomicPtr {
public:
     CachedAtomicPtr(): ptr_(nullptr) {}
>
     /// Store p in *this if *this is not yet assigned.
     /// Return pointer stored in *this, which can be \a p or not.
     Ptr<T> AssignIfNull(Ptr<T> p) {
         const T* other = nullptr;
         if (ptr_.compare_exchange_weak(other, p.get(), std::memory_order_release, std::memory_order_acquire)) {
             p->IncrementRefcount();
             return p;
         } else {
             // wrap in an extra smartptr (increments refcount)
             return Ptr<T>(other);
         }
     }
>
     /// Return pointer stored in *this,
     Ptr<T> Load() const {
         return Ptr<T>(ptr_);
     }
>
     ~CachedAtomicPtr() {
         if (const T* ptr = ptr_) {
             ptr->DecrementRefcount();
         }
     }
private:
     std::atomic<const T*> ptr_;
};
>
Example usage:
>
/// Objects of this class are in shared use by multiple threads.
class A {
     // Returns B corresponding to the value of *this.
     // If not yet in cache, B is calculated and cached in *this.
     // Calculating can happen in multiple threads in parallel,
     // the first cached result will be used in all threads.
     Ptr<B> GetOrCalcB() const {
         Ptr<B> b = cached_.Load();
         if (!b) {
             b = cached_.AssignIfNull(CalcB());
         }
         return b;
     }
     // ...
private:
     // Calculates cached B object according to value of *this.
     Ptr<B> CalcB() const;
private:
     mutable CachedAtomicPtr<B> cached_;
     // ... own data ...
};
>
So, what do you think? Should I just use std::atomic<std::shared_ptr> instead? Any other suggestions? Did I get the memory order parameters right in compare_exchange_weak()?
>
 I need to look at this when I get some time. Been very busy lately. Humm... Perhaps, when you get some free time to burn... Try to model it in Relacy and see what happens:
 https://www.1024cores.net/home/relacy-race-detector/rrd-introduction
 https://groups.google.com/g/relacy
 
Took a look at that. It appears for using Relacy I have to somehow translate my algorithm into Relacy-language, but this seems non-trivial. There is about zero documentation and zero code comments, and examples are not compiling with VS2022. Looks like for using it I would need to grow some 20 extra IQ points and spend a significant amount of time.

Date Sujet#  Auteur
15 Sep20:54 * Atomic caching of smart pointers23Paavo Helde
15 Sep22:13 +* Re: Atomic caching of smart pointers10Chris M. Thomasson
16 Sep23:31 i`* Re: Atomic caching of smart pointers9Paavo Helde
16 Sep23:46 i `* Re: Atomic caching of smart pointers8Chris M. Thomasson
16 Sep23:50 i  +* Re: Atomic caching of smart pointers2Chris M. Thomasson
17 Sep08:09 i  i`- Re: Atomic caching of smart pointers1Paavo Helde
17 Sep07:54 i  `* Re: Atomic caching of smart pointers5Paavo Helde
17 Sep07:59 i   `* Re: Atomic caching of smart pointers4Chris M. Thomasson
17 Sep08:04 i    `* Re: Atomic caching of smart pointers3Chris M. Thomasson
17 Sep11:22 i     `* Re: Atomic caching of smart pointers2Paavo Helde
17 Sep20:50 i      `- Re: Atomic caching of smart pointers1Chris M. Thomasson
15 Sep22:15 +* Re: Atomic caching of smart pointers8Chris M. Thomasson
16 Sep08:01 i`* Re: Atomic caching of smart pointers7Paavo Helde
16 Sep10:14 i +* Re: Atomic caching of smart pointers2Bonita Montero
16 Sep22:33 i i`- Re: Atomic caching of smart pointers1Chris M. Thomasson
16 Sep18:23 i +* Re: Atomic caching of smart pointers2Marcel Mueller
16 Sep22:34 i i`- Re: Atomic caching of smart pointers1Chris M. Thomasson
16 Sep19:06 i +- Re: Atomic caching of smart pointers1Bonita Montero
16 Sep22:01 i `- Re: Atomic caching of smart pointers1Chris M. Thomasson
16 Sep09:26 +* Re: Atomic caching of smart pointers2Muttley
16 Sep10:59 i`- Re: Atomic caching of smart pointers1Paavo Helde
16 Sep10:11 `* Re: Atomic caching of smart pointers2Bonita Montero
16 Sep22:12  `- Re: Atomic caching of smart pointers1Chris M. Thomasson

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal