[concurrency-interest] Single writer multiple readers no barriers -- safe ?

Aaron Grunthal aaron.grunthal at infinite-source.de
Fri Nov 29 17:00:02 EST 2013


Isn't the problem with both AtomicReferenceFieldUpdater and 
AtomicReference that they don't have a lazyGet? The get is equivalent to 
a volatile read. Only Unsafe can give you normal get and ordered put, 
i.e. safe single-writer publishing.


On 29.11.2013 22:04, Vitaly Davidovich wrote:
> AtomicReferenceFieldUpdater has some safety/defensive checking overhead,
> IIRC.  Although with writes every 5 mins only I don't think the write
> side perf matters all that much.
>
> Sent from my phone
>
> On Nov 29, 2013 2:37 PM, "Chris Vest" <mr.chrisvest at gmail.com
> <mailto:mr.chrisvest at gmail.com>> wrote:
>
>     Note that AtomicReferenceFieldUpdater also has lazySet, so you don't
>     need to go to the Unsafe if you want to avoid the indirection of
>     AtomicReference.
>
>     --
>     Chris
>
>
>     On 29 November 2013 10:06, Thomas Kountis <tkountis at gmail.com
>     <mailto:tkountis at gmail.com>> wrote:
>
>         Ok that makes sense.
>
>         I measured the performance and no this is not close to being a
>         bottleneck on the current setup, since there are other places
>         which are much slower. So the initial question was more into the
>         "lets experiment" side of things and learn. My thinking was that
>         since we only have one writer and thats only on a specific
>         interval (5 mins) there would be a waste of using the CHM to
>         host the data. Taking a snapshot of the current state during a
>         write, replace of things and reassign the map variable to the
>         snapshot seemed more interesting.
>
>         Thanks again :)
>
>
>
>         On Fri, Nov 29, 2013 at 8:42 AM, Nitsan Wakart
>         <nitsanw at yahoo.com <mailto:nitsanw at yahoo.com>> wrote:
>
>             What could go wrong is:
>                 while(getMap().get(key)){
>                    // wait for key
>               }
>             Can in theory (and sometimes in practice) spin forever. The
>             value gets hoisted and never checked again. The JIT assumes
>             there's no way for the read value to change, so won't check
>             again. At that point the 'at some point' becomes 'never'.
>             Reading through your original post again I would take a step
>             back and evaluate the performance win vs. correctness. Are
>             you 100% sure this is a bottleneck for your program? have
>             you tried and measured using CHM and it makes a measurable
>             difference to use your alternative?
>             If the answer to the above is "yes we did, and yes it does"
>             then it would be good to see some concrete code to
>             demonstrate how you are using this map.
>
>
>             On Friday, November 29, 2013 10:01 AM, Thomas Kountis
>             <tkountis at gmail.com <mailto:tkountis at gmail.com>> wrote:
>             Thanks for the responses guys.
>             I do understand all the above, but what I don't understand
>             is what could go wrong with the no barrier approach on x86 ?
>             Wouldn't that write eventually get flushed to main memory,
>             and the other processors must invalidate cache at some point
>             also ? I know this is a lot of "at some point", therefore, I
>             guess its very vague to be trusted, but is there anything
>             else apart from timing that could go wrong and that write
>             not become visible?
>
>             t.
>
>
>             On Fri, Nov 29, 2013 at 6:51 AM, Nitsan Wakart
>             <nitsanw at yahoo.com <mailto:nitsanw at yahoo.com>> wrote:
>
>                  From my experience, lazySet is indeed your best choice
>                 (but only a valid choice for a single writer). You need
>                 a volatile read to match the HB relationship otherwise
>                 the compiler is free to optimize the value you read, so
>                 someone using your map in a loop may end up stuck if you
>                 don't do it.
>
>
>
>                 On Friday, November 29, 2013 5:35 AM, Vitaly Davidovich
>                 <vitalyd at gmail.com <mailto:vitalyd at gmail.com>> wrote:
>                 AtomicReference.lazySet is the way to go here - on x86
>                 this is just normal mov instruction with compiler
>                 barrier only (StoreStore).  If you don't want overhead
>                 of AtomicReference wrapper (doesn't sound like that
>                 would be an issue) you can get same effect with
>                 Unsafe.putObjectOrdered.
>                 I wouldn't worry about AtomicReference.get() performance
>                 on x86 - this is a read from memory but if you read
>                 frequently, you'll hit L1 cache anyway.
>                 HTH
>                 Sent from my phone
>                 On Nov 28, 2013 5:34 PM, "Thomas Kountis"
>                 <tkountis at gmail.com <mailto:tkountis at gmail.com>> wrote:
>
>                     Hi all,
>
>                     This is my first time posting on this list, been
>                     follower for quite some time now and really enjoying
>                     all the knowledge sharing :) .
>
>                     I was looking on optimizing a solution today at
>                     work, and I came across the following.
>                     We have a scenario where we keep a simple cache
>                     (HashMap) and this is accessed by multiple
>                     readers on an application server, millions of times
>                     per day and highly contented. This cache is
>                     immutable and only gets updated by a single writer
>                     by replacing the reference that the variable points
>                     to every 5 mins. This is currently done as a
>                     volatile field. I was looking for a way to lose
>                     completely the memory barriers and rely on that
>                     field being eventually visible across all other
>                     threads (no problem by reading stale data for a few
>                     seconds).
>
>                     Would that be possible with the current JMM ? I
>                     tried to test that scenario with some code, and it
>                     seems to work most of the times, but some threads
>                     read stale data for longer that I would expect (lots
>                     of seconds). Is there any platform dependency on
>                     such implementation ? Its going to run on x86
>                     environments. Is there any assumption we can make as
>                     of how long that 'eventually' part can be ? (could
>                     it be more than 5 mins, when the next write
>                     occurs?). My understanding is that, that write even
>                     if re-ordered will have to happen. I came across an
>                     article about using the AtomicReference doing a
>                     lazySet (store-store) for the write, and then the
>                     Unsafe to do a getObject (direct) instead of the
>                     default get which is based on the volatile access.
>                     Would that be a better solution?
>
>                     Any ideas, alternatives?
>
>                     PS. Sorry for the question-bombing :/
>
>                     Regards,
>                     Thomas
>
>                     _______________________________________________
>                     Concurrency-interest mailing list
>                     Concurrency-interest at cs.oswego.edu
>                     <mailto:Concurrency-interest at cs.oswego.edu>
>                     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>                 _______________________________________________
>                 Concurrency-interest mailing list
>                 Concurrency-interest at cs.oswego.edu
>                 <mailto:Concurrency-interest at cs.oswego.edu>
>                 http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>
>
>
>
>
>
>         --
>         Thomas Kountis
>         PGP: 0x069D29A3
>
>         Q: "Whats the object-oriented way to become wealthy?"
>         A:  Inheritance
>
>
>         _______________________________________________
>         Concurrency-interest mailing list
>         Concurrency-interest at cs.oswego.edu
>         <mailto:Concurrency-interest at cs.oswego.edu>
>         http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
>     _______________________________________________
>     Concurrency-interest mailing list
>     Concurrency-interest at cs.oswego.edu
>     <mailto:Concurrency-interest at cs.oswego.edu>
>     http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>



More information about the Concurrency-interest mailing list