David Gallardo | 12 Dec 22:30 2007
Picon

Re: How bad can volatile long++ be?

 Goetz et al., in Java Concurrency in Practice, as this to say about that:

"When a thread reads a variable without synchronization, it may see a
stale value, but at least it sees a value that was actually placed
there by some thread rather than some random value. This safety
guarantee is called out-of-thin-air safety.

"Out-of-thin-air safety applies to all variables, with one exception:
64-bit numeric variables (double and long) that are not declared
volatile (see Section 3.1.4). The Java Memory Model requires fetch
and store operations to be atomic, but for nonvolatile long and
double variables, the JVM is permitted to treat a 64-bit read or
write as two separate 32-bit operations. If the reads and writes
occur in different threads, it is therefore possible to read a
nonvolatile long and get back the high 32 bits of one value and the
low 32 bits of another.[3] Thus, even if you don't care about stale
values, it is not safe to use shared mutable long and double
variables in multithreaded programs unless they are declared volatile
or guarded by a lock."

On Dec 12, 2007 1:51 PM, Osvaldo Pinali Doederlein
<osvaldo <at> visionnaire.com.br> wrote:
>
>  Hi,
>
>
>
>  ________________________________
>  From: Osvaldo Pinali Doederlein
>
(Continue reading)

Osvaldo Pinali Doederlein | 12 Dec 23:50 2007
Picon

Re: How bad can volatile long++ be?

David Gallardo escreveu:
Goetz et al., in Java Concurrency in Practice, as this to say about that: "When a thread reads a variable without synchronization, it may see a stale value, but at least it sees a value that was actually placed there by some thread rather than some random value. This safety guarantee is called out-of-thin-air safety. "Out-of-thin-air safety applies to all variables, with one exception: 64-bit numeric variables (double and long) that are not declared volatile (see Section 3.1.4). The Java Memory Model requires fetch and store operations to be atomic, but for nonvolatile long and double variables, the JVM is permitted to treat a 64-bit read or write as two separate 32-bit operations. If the reads and writes occur in different threads, it is therefore possible to read a nonvolatile long and get back the high 32 bits of one value and the low 32 bits of another.[3] Thus, even if you don't care about stale values, it is not safe to use shared mutable long and double variables in multithreaded programs unless they are declared volatile or guarded by a lock."
Right, but the discussion was not over the JMM and formal guarantees, it was about "what happens in practice", remarkably in best-case scenarios like: the system is a singleprocessor, the JVM generates optimal native code, and this code is the only code that matters (ignoring interpreted executions) - i.e., the assumptions that (unfortunately) many programmers make and then decide that some code is safe at least in a certain platform. Which is always wrong even for specific platforms, at least due to the interpreted code factor.

A+
Osvaldo
On Dec 12, 2007 1:51 PM, Osvaldo Pinali Doederlein <osvaldo <at> visionnaire.com.br> wrote:
Hi, ________________________________ From: Osvaldo Pinali Doederlein I am aware of the produced bytecode and other issues you mention. So I think I was not very clear in my comment, so trying again: 1) Code like the inc() below can be compiled down to a single instruction, which (at least on singleprocessors as several people pointed) is an atomic instruction. (*) Even on multicore/multiprocessors, I think the instruction will be atomic, provided that the long value is aligned to 8 bytes, which typically (always?) has the nice side effect of making sure the value doesn't straddle cache-line boundaries, so, no atomicity problems with the propagation of writes through the memory hierararchy. On X86, an increment instruction is not atomic on a multiprocessor (or presumably with "hyperthreading") unless it has a "lock" prefix. The lock prefix normally adds SUBSTANTIAL (order of a dozen to hundreds of cycles) overhead, and is unlikely to be generated without good reason. Hans Sorry, when I wrote that comment I was thinking too hard about Consistency, not Atomicity. I meant that the alignment should prevent, for example, that thread 1 writes 0x0000000000000000 and thread 2 concurrently writes 0xFFFFFFFFFFFFFFFF, and the result in memory is something like 0x00000000FFFFFFFF due to bad luck in cache-RAM sync'ing; but that's all (but correct me again if I am wrong even in this assumption). A+ Osvaldo -- ----------------------------------------------------------------------- Osvaldo Pinali Doederlein Visionnaire Informática S/A osvaldo <at> visionnaire.com.br http://www.visionnaire.com.br Arquiteto de Tecnologia +55 (41) 337-1000 #223 _______________________________________________ Concurrency-interest mailing list Concurrency-interest <at> altair.cs.oswego.edu http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest


-- ----------------------------------------------------------------------- Osvaldo Pinali Doederlein Visionnaire Informática S/A osvaldo <at> visionnaire.com.br http://www.visionnaire.com.br Arquiteto de Tecnologia +55 (41) 337-1000 #223
_______________________________________________
Concurrency-interest mailing list
Concurrency-interest <at> altair.cs.oswego.edu
http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
Mark Thornton | 12 Dec 23:00 2007
Picon

Re: How bad can volatile long++ be?

David Gallardo wrote:
>  Goetz et al., in Java Concurrency in Practice, as this to say about that:
>
> "When a thread reads a variable without synchronization, it may see a
> stale value, but at least it sees a value that was actually placed
> there by some thread rather than some random value. This safety
> guarantee is called out-of-thin-air safety.
>
> "Out-of-thin-air safety applies to all variables, with one exception:
> 64-bit numeric variables (double and long) that are not declared
> volatile (see Section 3.1.4). The Java Memory Model requires fetch
> and store operations to be atomic, but for nonvolatile long and
> double variables, the JVM is permitted to treat a 64-bit read or
> write as two separate 32-bit operations. If the reads and writes
> occur in different threads, it is therefore possible to read a
> nonvolatile long and get back the high 32 bits of one value and the
> low 32 bits of another.[3] Thus, even if you don't care about stale
> values, it is not safe to use shared mutable long and double
> variables in multithreaded programs unless they are declared volatile
> or guarded by a lock."
>
>   
I think Osvaldo was assuming that long (or double) reads/writes would be 
atomic on a 64 bit JVM. It is certainly not true on a typical 32 bit x86 
JVM.

Mark Thornton

Gmane