5

I just read this puzzling line in Peter Richtie blog and I need help to understand the meaning Prior to .NET 4.5 you really programmed to the .NET memory model : http://msmvps.com/blogs/peterritchie/archive/2012/09/09/thread-synchronization-of-atomic-invariants-in-net-4-5.aspx

Has the 'usual' .NET memory model (such as the one discussed in Jeffrey Richter book CLR via C# edition 1 and 2 (I haven't read 3d)) changed in .NET 4.5?

Is there an article with conscious explanation?

leppie
  • 115,091
  • 17
  • 196
  • 297
Boppity Bop
  • 9,613
  • 13
  • 72
  • 151

1 Answers1

2

The proper way to handle concurrency in .NET is based on a weak memory model. This hasn't changed in .NET 4.5.

Just because Itanium is no longer supported doesn't mean you can assume the stronger x86 or amd64 memory models. For instance, you have other weak memory model platforms, such as ARM.

Always remember that non-volatile reads to the same variable or field may be elided after the first one by the JIT compiler, in case it can prove there is no synchronization between reads (memory barriers, monitor lock of an object that is/was monitor unlocked, volatile read of a variable that was volatile written, Interlocked operations on a variable). This respects the thread's point of view consistency.

The article you linked to shows examples where Microsoft .NET Framework's JIT compiler elides reads in e.g. while loops that read a non-volatile variable without any synchronization point inside the loop. But remember, a JIT compiler could use whole program optimizations to generalize this elision between callers and callees.

As such, lock-free algorithms in .NET that read a variable or field without memory barriers, locks, volatile semantics or Interlocked operations, on the premise that these reads will eventually see changes from other threads, are gambling with the JIT compiler. In essence, these algorithms are wrong in terms of portability.

Which makes me wonder, why do you ask this?

acelent
  • 7,965
  • 21
  • 39
  • we live in different universes. it pays to know here.. perhaps it pays to write portable applications in .NET in your universe.. I am not bothered with it.. are you? – Boppity Bop Nov 23 '16 at 14:11
  • I expect some of my .NET libraries (shared among different targets) to work properly in 32-bit and 64-bit and in strong memory models and weak memory models. I'm not even considering portability outside of the Microsoft platforms. For instance, some of the currently most popular NuGet packages (Json.NET, NLog) work in both Windows Server 2012 R2 (amd64) and Windows Phone 8.1 or Windows 10 Mobile (possibly ARM). What if the authors didn't care about portability? It's not that hard to get concurrency right, what's hard is e.g. to optimize, refactor code to avoid lock contention, etc. – acelent Nov 23 '16 at 15:08
  • I understand that, from your point of view, you may bite the bullet. Personally, I prefer to have code ready for the weaker memory model. For instance, I start using locks to get to a correct implementation, then iterate towards volatile fields and/or `Interlocked` operations. If you decide to go with unguarded reads, at least do so knowingly that "It works on your machine(s)". – acelent Nov 23 '16 at 15:10
  • yeah.. I am doing it.. for 5 yrs now.. and it works on the machines I paid to make it work. I am not a blog writer ;) – Boppity Bop Nov 23 '16 at 15:19