Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost][sync?] "Distributed" value (or something...)
From: Klaim - Joël Lamotte (mjklaim_at_[hidden])
Date: 2014-07-31 04:34:08


On Wed, Jul 30, 2014 at 11:39 AM, Gavin Lambert <gavinl_at_[hidden]>
wrote:

> On 30/07/2014 20:35, Klaim - Joël Lamotte wrote:
>
>> A really simple (albeit heavy-handed) way of doing this lock-free
>> (or almost lock-free, depending on shared_ptr implementation) is to
>> have your data in a shared_ptr; whenever something wants to act on
>> the data it uses atomic_load to fetch it from some well-known
>> location and can then do whatever read-only access it wishes; when
>> it wants to change the data it first copies the entire object, makes
>> the changes in the copy, and then uses atomic_compare_exchange to
>> replace the "real" version. If the compare fails, it lost the race
>> to a faster writer so must perform its updates again on the new data
>> and try exchanging again.
>>
>>
>> This would work I guess but not well with big values (like a big struct).
>> Also, from my understanding, having one "copy" of the object for each
>> subscriber seems to be potentially more efficient if you already know
>> that each subscriber work with it's own thread (or set of threads).
>>
>
> Copies are not efficient for a big struct, but copies only occur on write
> so it's not a big deal if writes are rare.
>
>
Yes I believe that at least in my use case it makes sense.

> Having a separate copy for each subscriber is helpful to avoid write
> contention, but if everything is only reading from a single shared object
> that is seldom written to then I don't think it provides any benefit (but
> I'm not an expert on cache effects).
>
>
I'm not an expert either so I might be pessimizing that part.
I started an implementation and will try to make the interface not impact
the implementation so that I can try different things.

> My gut feeling is that which approach is "better" depends on the number of
> subscribers and the frequency of actions. You do pay a bit for an atomic
> load/exchange (it's not a lot, but it's still something you want to avoid
> doing in a tight loop), but it means you only need to copy once; conversely
> having copies for each subscriber lets you avoid the atomics but requires
> you to make N copies.
>
>
In my case it's ok to have N copies, but yeah I have to make sure the user
understand this cost.

> There are other tradeoffs as well, of course -- the one I proposed above
> doesn't have notifications on change, it just lets existing operations
> continue using the old data while new operations silently pick up the new
> data (basically a pull model); while a push model explicitly notifies
> subscribers that new data is available and lets them potentially do
> something esoteric if required -- but if implemented naively may result in
> the subscribers all being called from the publisher's thread, which may
> introduce contention and cache fragmentation.
>
>
I'll try to make my implementation possible to use either with callbacks
called using executors, or through an regular pull call.
Both seems interesting in different cases and it don't seem to me (at the
moment) that implementation of both would be mutually exclusive.

I'll report here when I have something that I can at least use in my own
project.

>
>
> _______________________________________________
> Boost-users mailing list
> Boost-users_at_[hidden]
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
>



Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net