5

Example:

Thread a:  Interlocked.Increment(ref x);

Thread b:  int currentValue = x;

Assuming thread b executes after thread a, is "currentValue" in thread b guaranteed to be the incremented value? Or, does thread b need to do a Thread.VolatileRead(ref x)?

noctonura
  • 12,763
  • 10
  • 52
  • 85

2 Answers2

5

Technically that depends on the CPU .NET is running on, but for any common CPU the answer is yes, cache coherency is guaranteed for an Interlocked.Increment. It acts as a memory barrier as required by MESI.

a CPU can have in its cache a line which is invalid, but where it doesn't yet know that line is invalid - the invalidation queue contains the invalidation which hasn't yet been acted upon. (The invalidation queue is on the other "side" of the cache; the CPU can't scan it, as it can the store buffer). As a result, memory barriers are required.

http://en.wikipedia.org/wiki/MESI_protocol (x86)

MOESI (used on AMD64 chips) is quite similar:

http://en.wikipedia.org/wiki/MOESI_protocol (AMD64)

Community
  • 1
  • 1
Eric J.
  • 147,927
  • 63
  • 340
  • 553
3

As I understand it, Interlocked is only guaranteed when accessed by other Interlocked methods. This may be especially important when talking about 64-bit values on x86 systems, where it cannot be guaranteed to be atomic, so torn values are a concern. A good trick for robustly reading a value that can be changed by Interlocked is CompareExchange:

int val = Interlocked.CompareExchange(ref field, 0, 0);

This mutates the value of field to 0, but only if the old value was 0 - otherwise it does nothing. Either way the old value is returned. So basically: it reads the value without ever changing it, and is safe vs other Interlocked methods.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 1
    Good point, but does not directly address *cache coherency*. As far as I understand it, the *cache* is guaranteed to be consistent at any point in time. However, when reading without Interlocked, there is no memory barrier to prevent torn values. My understanding on this point is incomplete though. I would appreciate any references that shed further light. – Eric J. Dec 13 '12 at 00:03