Boost logo

Boost Users :

Subject: Re: [Boost-users] [boost][sync?] "Distributed" value (or something...)
From: Gavin Lambert (gavinl_at_[hidden])
Date: 2014-07-30 05:39:42


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.

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).

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.

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.


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