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]

Re: Optimization of conditional stores


On 04/07/14 08:41, Alexander Monakov wrote:
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.
You might want to check the C11/C++11 standard to be sure. There's a reasonable chance the memory model disallows this kind of transformation.

jeff


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