Answer the question
In order to leave comments, you need to log in
[.NET] Is getting/writing an array element by index an atomic operation?
In various .NET collections, indexers are properties, and it is clear that getting or setting an element by index is not an atomic operation in this case.
I'm wondering if there is an exception for arrays in this case?
Can such an operation have the right to life, or can the access through the indexer and the installation back be interrupted by a context switch?
int original = Interlocked.CompareExchange(ref array[2], 5, 3);
The reference to the array does not change, only the values of the elements in the cells are changed by different threads. IL_0017: ldloc.0 // 'array'
IL_0018: ldc.i4.2
IL_0019: ldelema [mscorlib]System.Int32
IL_001e: ldc.i4.5
IL_001f: ldc.i4.3
IL_0020: call int32 [mscorlib]System.Threading.Interlocked::CompareExchange(int32&, int32, int32)
IL_0025: pop
I'm still inclined to believe that the operation is atomic, but it's better to get the opinion of a knowledgeable person.
Answer the question
In order to leave comments, you need to log in
IL code is only half the battle.
The version of the VM and the bitness of the assembly are important, debug / release mode.
Use windbg, there you can see the code of the method that will be executed by the CPU.
I'm not answering the question, but giving food for thought.
Book - "Goldstein S. - Optimization of applications on the .NET platform - 2014".
Excerpts from the book:
"Writing a 32-bit integer is always done atomically. This means that if a processor writes the value 0xdeadbeef to a memory location previously initialized to zero, another processor will never receive the partially modified value in that location."
"Unfortunately, the same cannot be said for larger data; for example, even on a 64-bit processor, a 20-byte write operation is not atomic and cannot be atomic."
"Whenever an operation on a region of memory requires the execution of several instructions, a synchronization problem immediately arises. For example, the operation ++i (where i is a variable on the stack of type int) is usually translated into a sequence of three machine instructions:
mov еах, dword ptr [ebp-64] ; скопировать со стека в регистр
inc еах ; увеличить значение в регистре
mov dword ptr [ebp-64], еах ; скопировать из регистра на стек
// Код на С#:
int n = . . .;
if (Interlocked.CompareExchange(ref n, 1, 0) = 0) ( // заменить 0 на 1
// ...выполнить некоторые операции
}
// инструкции на языке ассемблера х8б:
mov еах, 0 ;
mov edx, 1 ;
lock cmpxchg dword ptr [ebp-64], edx ;
test eax, eax ;
i
jnz not__taken
// ... выполнить некоторые операции
not_taken:
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question