What is Interlocked.Increment actually doing?
Asked Answered
A

3

24

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)

Aron answered 18/4, 2011 at 8:6 Comment(1)
I have to say that your assumption, that it is some sort of pattern and everybody doing multithreaded code would know it is lovely, but ultimately untrue. I have to add, UNFORTUNATELY:). Based on my experiences, many people consider interlocked strange, unnecessary in general or worse, do not consider them at all, as they do not know interlocked methods.Panlogism
A
15

According to Mr Albahari it does two things:

  • makes the atomicity of the operation known to the OS and VM, so that e.g. operations on 64bit values on 32bit system will be atomic
  • generates full fence restricting reordering and caching of the Interlocked vars

Have a look at that link - it gives some nice examples.

Almswoman answered 18/4, 2011 at 8:20 Comment(1)
on x86/64 after cas you dont need extra fence. and usually the impl is just a loop load/increment/cas (break on successful cas)Boondoggle
V
9

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
Vagabondage answered 18/4, 2011 at 8:35 Comment(2)
Could you tell the reason why it uses "lock xadd" on x64 instead of "lock add"?Ulysses
How would lock inc dword <location> handle the return value?Roubaix
G
1

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.

Gladi answered 18/4, 2011 at 8:12 Comment(3)
The Interlocked Win32 APIs are implemented as compiler intrinsicsRicebird
@David True for 64 bit windows, but they are available for 32-bit one. In any case, Brian's answer already provides the answer by examining the JIT output, which shows that the code emits the necessary x86 instructions directly.Gladi
Even in 32 bit, they are implemented as compiler intrinsics. There are exports available from kernel32 but all recent compilers use intrinsics for the obvious performance reasonsRicebird

© 2022 - 2024 — McMap. All rights reserved.