Interlocked.Increment
seems like among the most standard/simple of operations one would need to perform in multithreaded code.
I assume that the functionality of the method is some sort pattern that anyone with threading experience would be able to replicate.
So basically what I am wondering is if someone could provide an exact duplicate (with explanation of how it works) of what the Interlocked.Increment
method is actually doing internally? (I have looked for the source of the actual method but been unable to find it)
The first part (load-link) reads a value from memory and instructions the processor to monitor the memory address to see if any other processors modify that same memory. The second part (store-conditional) stores a value to memory provided that no other processors have written to the memory in the meantime.
It is slower since it forces the action to occur atomically and it acts as a memory barrier, eliminating the processor's ability to re-order memory accesses around the instruction. You should be using Interlocked.
The Interlocked class provides a number of static methods that perform atomic operations. These can generally be regarded as thread-safe.
Interlock. Exchange returns the original value while performing an atomic operation. The whole point is to provide a locking mechanism. So it is actually two operations: read original value and set new value. Those two together are not atomic.
According to Mr Albahari it does two things:
full fence
restricting reordering and caching of the Interlocked varsHave a look at that link - it gives some nice examples.
I assume that it is an implementation detail, but one way to look at it is to inspect the JIT compiled code. Consider the following sample.
private static int Value = 42;
public static void Foo() {
Interlocked.Increment(ref Value);
}
On x86 it generates the following
lock inc dword <LOCATION>
The lock modifier locks the bus to prevent multiple CPUs from updating the same data location.
On x64 it generates
lock xadd dword ptr <LOCATION>,eax
I would expect it to be a wrapper to the InterlockedIncrement64 Win32 API call.
EDIT: I see that it was a very short response. Building a little on it: It is easy to replicate the functionality of the function, but not the performance. There are native instructions in most CPUs that provide you with the atomic "Interlocked exchange and add" instruction, so you want that instruction to be used to implement your function, and I expect that the easiest way to achieve that from within C# would be to make the win32 API call. For more background on the subject, have a look at this whitepaper.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With