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

Vitaly Davidovich vitalyd at gmail.com
Fri Nov 29 17:44:13 EST 2013


On x86 the volatile read isn't going to cost much of anything over a normal
one - it's just a compiler barrier.  If it's read often it'll be in L1
cache and be just a few clocks.

Using a naked read leaves you open to the scenario Nitsan mentioned earlier
in this thread.

Sent from my phone
On Nov 29, 2013 5:02 PM, "Aaron Grunthal" <aaron.grunthal at infinite-source.de>
wrote:

> 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
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20131129/2258919c/attachment-0001.html>


More information about the Concurrency-interest mailing list