InterlockedIncrement vs InterlockedIncrementAcquir

2019-09-03 19:01发布

问题:

This question already has an answer here:

  • What's the difference between InterlockedCompareExchange Release() and Acquire()? 2 answers

Can someone explain the difference betweeen these three atomic operations?

  • InterlockedIncrement
  • InterlockedIncrementAcquire
  • InterlockedIncrementNoFence

I can't seem to find any documentation on what they mean other than "uses acquire symantecs" which I don't understand.

Thanks.

回答1:

Going off the documentation,

InterlockedIncrement "generates a full memory barrier" for every call. Memory barriers are special instructions to your CPU that prevent it from reordering operations like it usually does -- for instance, load operations can be very expensive, so given a stream of ops that look like "add to A, add to A, load B, add to B", the CPU will attempt to reorder it as "load B, add to A, add to A, add to B" so that the load of B has time to complete before it's needed.

However, this can destroy logic in parallel programs, so sometimes memory barriers are necessary. They're expensive: they tend to cost around as much as a cache miss.

InterlockedIncrementAcquire tries to use "acquire semantics" if supported by your system, if not, it falls back to InterlockedIncrement. Going off of that blog post,

Acquire semantics prevent memory reordering of the read-acquire with any read or write operation which follows it in program order

So acquire semantics are a limited, less-expensive kind of memory barrier that's only useful in certain situations (when only reads are involved, evidently).

Finally, InterlockedIncrementNoFence generates no memory barrier -- it's completely unchecked, and it's possible that it will cause you issues with sequential consistency.