Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Some questions about thread synchronization

I'm having some questions I'd like to clarify.

  1. Volatile read ensure you read the latest value of a variable. Does it means that it forces to all CPU's to flush their cached values for that variable? only that variable or all? So if it will force all CPUs to flush cached writes and get latest version from main memory, is this a memory barrier?

  2. Volatile write ensure you write a value to the variable in main memory. Does it means that it void all the cached values for that variable in all CPUs?

  3. Are you using a memory barrier when you use the keyword volatile?

  4. Interloked performs a read/modify/write in an atomic operation. Does Interlocked ensure that you are for example incrementing the latest version of a variable and the other CPUs will see this change? I think so because it's supposed to use a memory barrier, but I'm not sure. So could we say that Interloked is doing a VolatileRead/modify/VolatileWrite atomically?

  5. When you use a memory barrier, does it affect to all variables in all CPUS, or just the surrounding ones?

  6. Locking is expensive because it causes two memory barriers and a "context switch" if the thread has to wait, but then what is the advantage of Interlocked? just to avoid the "context switch"?

  7. What is the deal with ReaderWriterLockSlim and recursivity? I didn't understans what is the issue.

As you can see, I have a total mess in my mind right now.

Thanks in advance.

like image 377
vtortola Avatar asked Nov 18 '10 13:11

vtortola


2 Answers

Before answering your questions I should point out that memory barriers affect more than just the CPU. There are really two memory models in play when an application runs. One is at the hardware level and the other is at the software level. As a developer you have to code for the weakest combination of the different elements from both. With the CLR and an x86 architecture this usually means the CLR is more important because the x86 architecture actually has a fairly strong memory model. In other words, the volatile keyword and other memory barriers mechanisms will affect how the JIT produces code as well.

1.Volatile read ensure you read the latest value of a variable. Does it means that it forces to all CPU's to flush their cached values for that variable? only that variable or all? So if it will force all CPUs to flush cached writes and get latest version from main memory, is this a memory barrier?

First, technically a volatile read does not ensure you read the latest value of a variable. All it actually means is that no other read or write can occur before the volatile one. However, the effect is that the read has to come from main memory if it is preceded by another volatile read. Second, no, a volatile read has no influence on other writes so it does not force all CPUs to flush their write cache. Third, yes a volatile operation is considered a memory barrier.

2.Volatile write ensure you write a value to the variable in main memory. Does it means that it void all the cached values for that variable in all CPUs?

Similiar to a volatile read, a volatile write is technically about ordering. It ensures that no other read or write can occur after the volatile one. It does not mean that the write in question immediately gets committed. It only affects the CPU executing that thread. Interestingly, the x86 architecture actually treats all writes as volatile. But, the CLR does not (at least the ECMA specification). That is why you still have to use a volatile operation on writes. This is one example of coding for the weakest memory model element from both the hardware and software level.

3.Are you using a memory barrier when you use the keyword volatile?

Yes. There are two types of memory barriers. Full fences and half fences. Half fences can either guarentee acquire semantics (volatile read) or release semantics (volatile write), but not both at the same time. A full fence (via Thread.MemoryBarrier for example) guarentees both.

4.Interloked performs a read/modify/write in an atomic operation. Does Interlocked ensure that you are for example incrementing the latest version of a variable and the other CPUs will see this change? I think so because it's supposed to use a memory barrier, but I'm not sure. So could we say that Interloked is doing a VolatileRead/modify/VolatileWrite atomically?

Yep. And for what is worth the interlocked increment and decrement operations can be implemented with a CAS operation. In .NET you would use the Interlocked.CompareExchange method in a loop until the operation succeeded. I bet the Interlocked.Increment and Interlocked.Decrement methods use a native CPU instruction though, but I am prepared to be wrong about that.

5.When you use a memory barrier, does it affect to all variables in all CPUS, or just the surrounding ones?

It will affect all memory accesses, but only on the CPU executing that thread.

6.Locking is expensive because it causes two memory barriers and a "context switch" if the thread has to wait, but then what is the advantage of Interlocked? just to avoid the "context switch"?

Yeah basically. The thread never blocks with interlocked operations.

7.What is the deal with ReaderWriterLockSlim and recursivity? I didn't understans what is the issue.

You cannot acquire the lock twice on the same thread without first releasing it. There is more information on Joe Duffy's blog.

like image 197
Brian Gideon Avatar answered Oct 10 '22 03:10

Brian Gideon


One problem with locks is that any thread that acquires a lock must assume the risk that other threads may hold the lock for an arbitrary length of time. A Threading.Interlocked.CompareExchange call is guaranteed to return almost instantly (whether it succeeds or not); except under conditions of deliberately-heavy contention, a short CompareExchange spinlock will also return quickly. If a thread acquires a lock and then goes off and does other things before it releases it, other threads will have to wait for those other things to finish before they can acquire the lock. No such danger exists with a CompareExchange spinlock. Unless other threads are actively hitting spinlock themselves, the spinlock will complete quickly.

like image 40
supercat Avatar answered Oct 10 '22 03:10

supercat