[concurrency-interest] RFR: 8065804: JEP 171: Clarifications/corrections for fence intrinsics
David Holmes
david.holmes at oracle.com
Sun Dec 7 22:40:41 UTC 2014
On 6/12/2014 7:49 AM, Martin Buchholz wrote:
> On Thu, Dec 4, 2014 at 5:55 PM, David Holmes <david.holmes at oracle.com> wrote:
>
>> In general phrasing like: " also known as a LoadLoad plus LoadStore barrier
>> ..." is misleading to me as these are not "aliases"- the loadFence (in this
>> case) is being specified to have the same semantics as the
>> loadload|storeload. It should say "corresponds to a LoadLoad plus LoadStore
>> barrier"
>
> + * Ensures that loads before the fence will not be reordered with loads and
> + * stores after the fence; also known as a LoadLoad plus LoadStore barrier,
>
> I don't understand this. I believe they _are_ aliases. The first
> clause perfectly describes a "LoadLoad plus LoadStore barrier".
I find the language use inappropriate - you are defining the first to be
the second.
> - as per the "Corresponds to a C11 ...". And referring to things
>> like "load-acquire fence" is meaningless without some reference to a
>> definition - who defines a load-acquire fence? Is there a universal
>> definition? I would be okay with something looser eg:
>
> Well, I'm defining "load-acquire fence" here in the javadoc - I'm
> claiming that loadFence is also known via other terminology, including
> "load-acquire fence". Although it's true that "load-acquire fence" is
> also used to refer to the corresponding C11 fence, which has subtly
> different semantics.
When you say "also known as XXX" it means that XXX is already defined
elsewhere. Unless there is a generally accepted definition of XXX then
this doesn't add much value.
>> /**
>> * Ensures that loads before the fence will not be reordered with loads and
>> * stores after the fence. Corresponds to a LoadLoad plus LoadStore
>> barrier,
>> * and also to the C11 atomic_thread_fence(memory_order_acquire).
>> * Sometimes referred to as a "load-acquire fence".
>> *
>>
>> Also I find this comment strange:
>>
>> ! * A pure StoreStore fence is not provided, since the addition of
>> LoadStore
>> ! * is almost always desired, and most current hardware instructions
>> that
>> ! * provide a StoreStore barrier also provide a LoadStore barrier for
>> free.
>>
>> because inside hotspot we use storeStore barriers a lot, without any
>> loadStore at the same point.
>
> I believe the use of e.g. OrderAccess::storestore in the hotspot
> sources is unfortunate.
I don't! Not at all!
> The actual implementations of storestore (see below) seem to
> universally give you the stronger ::release barrier,
Don't conflate hardware barriers and compiler barriers. On TSO systems
storestore() is a no-op for the hardware but a compiler-barrier is still
required. The compiler barrier is stronger than storestore but that's
because we don't have fine-grained compiler barriers. As I've said
previously there is an open bug to clean up the orderAccess definitions
because semantically it is very misleading to define things like
storestore() as release(). However if you look at the implementation of
things we are not actually adding any additional semantics to the
storestore(). Eg for x86 (after a recent change top cleanup the
compiler-barrier:
inline void OrderAccess::release() {
compiler_barrier();
}
So storestore() is also just a compiler barrier, thought I'd prefer to
see it expressed as:
inline void OrderAccess::storestore() { compiler_barrier(); }
than the misleading (and very wrong on non-TSO):
inline void OrderAccess::storestore() { release(); }
And of course the non-TSO platforms use the barrier necessary on that
platform.
> and it seems
> likely that hotspot engineers are implicitly relying on that, that
> some uses of ::storestore in the hotspot sources are bugs (should be
> ::release instead)
That seems a rather baseless speculation on your part. Having been
involved in a lot of discussions involving memory barrier usage in
various algorithms in different areas of hotspot I can assure you that
the use of storestore() has been quite deliberate and does not assume an
implicit loadstore().
Also as I've said many many times now release() as a stand-alone
operation is meaningless.
David
-----
and that there is very little potential performance
> benefit from using ::storestore instead of ::release, precisely
> because the additional loadstore barrier is very close to free on all
> current hardware. Writing correct code using ::storestore is harder
> than ::release, which is already difficult enough. C11 doesn't provide
> a corresponding fence, which is a strong hint.
>
>
> ./bsd_zero/vm/orderAccess_bsd_zero.inline.hpp:71:inline void
> OrderAccess::storestore() { release(); }
> ./linux_sparc/vm/orderAccess_linux_sparc.inline.hpp:35:inline void
> OrderAccess::storestore() { release(); }
> ./aix_ppc/vm/orderAccess_aix_ppc.inline.hpp:73:inline void
> OrderAccess::storestore() { inlasm_lwsync(); }
> ./linux_zero/vm/orderAccess_linux_zero.inline.hpp:70:inline void
> OrderAccess::storestore() { release(); }
> ./solaris_sparc/vm/orderAccess_solaris_sparc.inline.hpp:40:inline void
> OrderAccess::storestore() { release(); }
> ./linux_ppc/vm/orderAccess_linux_ppc.inline.hpp:75:inline void
> OrderAccess::storestore() { inlasm_lwsync(); }
> ./solaris_x86/vm/orderAccess_solaris_x86.inline.hpp:40:inline void
> OrderAccess::storestore() { release(); }
> ./linux_x86/vm/orderAccess_linux_x86.inline.hpp:35:inline void
> OrderAccess::storestore() { release(); }
> ./bsd_x86/vm/orderAccess_bsd_x86.inline.hpp:35:inline void
> OrderAccess::storestore() { release(); }
> ./windows_x86/vm/orderAccess_windows_x86.inline.hpp:35:inline void
> OrderAccess::storestore() { release(); }
>
More information about the core-libs-dev
mailing list