This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Optimization of conditional stores (was: Re: [PATCH] Add adaptive elision to rwlocks)


On Fri, 4 Apr 2014, Roland McGrath wrote:
> > This is an important optimization to avoid unnecessary cache line
> > transitions and aborts. In general unnecessary writes
> > can be very expensive in parallel situations, as hardware
> > may need to do a lot of work to transition the cache line
> > from SHARED to EXCLUSIVE.
> > 
> > I can add a comment.
> 
> I think you might need to do more than that if you want to ensure the
> compiler never makes a different choice for you.  I'm not positive,
> but I think the rules of C allow it to transform the one into the
> other ("optimizing out" the test and branch in favor of a write that
> might be a no-op).  In the absence of volatile (or atomic ops or
> whatnot) then I don't think there are any actual guarantees about
> anything like e.g.  preserving semantics that if the value was already
> what you tested for then the page will never see a write access.  Even
> if compilers don't violate our presumptions about this today, they
> might in the future unless the C standard constrains them.  And even
> if the target hardware in question will never make that a wise
> optimization decision and so the compiler will never do it, we should
> still express to the compiler the constraints we want it to obey as
> best we can.  So--unless I'm wrong about what the standard specifies,
> which I'm not entirely sure about--then I think we should implement
> these cases with something explicit.  It could start out as just a
> macro that serves as documentation of the intent, while we look into
> what we can or should do to express that intent to the compiler.  e.g.
> 
> #define assign_probably_same(var, val) ({ if (var != val) var = val; var; })
> 
> (or perhaps get fancier to avoid multiple evaluation or something).

The compiler is not allowed to always translate a conditional store:

    if (*ptr != value)
        *ptr = value;

into an unconditional store, because `ptr' might point to read-only memory.

If the compiler can prove that `ptr' must be pointing to writeable location
(for instance if there is a preceding (dominating) unconditional store), it
can, and likely will, perform the optimization.

I would also suggest making the intent (perform the store only when necessary)
explicit, and make sure to disallow the compiler optimization, for example:

    if (*ptr != value)
        *(volatile typeof(*ptr)*)ptr = value;

Alexander


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]