[concurrency-interest] memory barriers

Bill Pugh pugh@cs.umd.edu
Thu, 29 Jan 2004 17:17:35 -0500

At 12:53 PM +0100 1/29/04, Kasper Nielsen wrote:
>The question was really if the statement
>Changes to fields made by one thread are guaranteed to be visible to 
>other threads only under the following conditions:
>A writing thread releases a synchronization lock and a reading thread
>subsequently acquires that _same_ synchronization lock.
>do it really need to be the _same_ synchronization lock?

Yes, it needs to be the _same_ synchronization lock. Several reasons for this:

* It allows compilers and JVMs to remove synchronization on thread local
* It allows more efficient implementation of synchronization on some SMPs
   (e.g., it doesn't require that synchronization involve a global memory
   barrier, which can be expensive on a system such as a large IA64 cluster).
* Code that depends on ordering by synchronization on two different locks
   is almost certainly broken. For example, in the code you gave, even if
   synchronization was a global memory barrier, there is nothing to 
prevent print
   from seeing the value 4, since you have no way of knowing that one
   synchronized preceded the other (in fact, their executions could overlap).

>>The JMM spec is unclear about memory barriers so they can removed when it is
>>determined they are not needed.  (In addition, memory barriers per se may
>>not exist on some platforms.)

This is all described in the new JMM

>They have something similar on the .NET platform

Yes, and it is a bad design choice, and the documentation is 
incorrect. They say:

>MemoryBarrier is required only on multiprocessor systems with weak 
>memory ordering (for example, a system employing multiple Intel 
>Itanium processors).

But in fact, ia32 architectures allow some reorderings, and need 
memory barriers or other synchronization constructs in certain 
circumstances. More importantly, I suspect we will get lots of C# 
code that, intentionally leaves out memory barriers, resulting in 
code that runs correctly only on ia32. When memory barriers are used, 
they will result in code slower than if proper synchronization had 
been used.

Bill Pugh