Make load/store of 64-bit long and double atomic
John Crowley
jdcrowley at gmail.com
Tue Jul 12 11:50:53 UTC 2016
John Crowley
Westport, CT
203-856-2396
> On Jul 11, 2016, at 10:21 PM, David Holmes <david.holmes at oracle.com> wrote:
>
> Hi John,
>
> On 7/07/2016 9:29 PM, John Crowley wrote:
>> All:
>>
>> Would like to make a suggestion re the JVM and non-atomic load/store for long and double values since both are 64-bit. (Sec 17.7 of the JLS version 8 - have not been able to find a JLS V9 yet). Did some searching through JSRs and mailing lists, but did not see this addressed - please send me a link if it has been and I just missed it.
>
> This is not a hotspot issue but a Java programming language issue. Hotspot would never provide a flag that changes the Java programming language semantics. The performance impact of all-accesses-are-atomic on 32-bit systems is considerable so as long as we support 32-bit I don't see this happening (regardless of what may be discussed on jmm-dev). It would be unconscionable to have different semantics on 32-bit and 64-bit so that is not an option either.
Certainly not suggesting that Hotspot unilaterally make this change. Would expect it to be discussed, considered through the JSR (or other) process, and coordinated with some future releases of Java and the JVM. Would also need to be discussed and published to the multiple other languages which compile to the JVM.
The suggested implementations are intended so that the defaults do not change the current semantics, and the user must choose if the atomic load/store semantics are activated.
Agree that the performance hit on 32-bit systems would be dramatic, hence options to operate either way as a developer decision. Expect that the vast majority of Java code is already executing on 64-bit machines, and the current situation requires use of volatile so we are imposing an extra memory barrier (and possibly disallowing some optimizations) where it is not required. Also agree that 32-bit support will be required in the future, especially if the JVM is used in embedded applications or other environments where 64-bit architectures will never be present, so these can choose the non-atomic semantics.
Understand, I don’t really like having to make this choice at the JVM level, but feel that it eliminates a "gotcha" in the language and provides the most efficient processing for the vast majority of standard Java executions.
IMHO the current situation already has different semantics on 32-bit vs 64-bit architectures. Most 64-bit architectures have atomic load/store of long and double primitives, where 32-bit architectures have split operations - this suggestion is trying to eliminate this difference.
>
> I also think this is somewhat of a red-herring. If lack of atomic accesses is causing your code a problem then your code is not performing atomic updates of variables - ie modifications to longs/doubles are not being done in a thread-safe way. Making simple reads/writes atomic will not change that - your code will still be broken.
Was primarily thinking of situations where only 1 thread writes to the variable, but there are multiple readers. Example, posting currentTimeInMillis when some worker thread completes a stage of a computation (e.g. message sent or received).
>
>> Right now, in a multi-threaded environment the developer must make these volatile to ensure correct operation - which I would suspect that 95% of Java developers do not realize. (I certainly didn’t for over 20 years!)
>
> Any introductory Java text worth its salt, and certainly any text on concurrent programming in Java, covers this part of the programming model.
Read my last introductory Java text in 1996 (I believe), and was trying to get "Hello, world!" to run - certainly not considering at all the subtle details of multi-threaded programming. Suspect that a large number of Java developers working on standard business applications, who started when all programs were single-threaded anyway, may not realize this point.
>
>> Worse, in most cases these will in fact be atomic on any 64-bit server, and non-atomic on a 32-bit architecture - so you may suddenly get very strange differences running the same codebase. [Are there any 64-bit JVMs in which these load/store operations are done in 32-bit chunks?]
>
> Unaligned accesses to 64-bit variables may not be atomic on some architectures.
Good point.
>
> Cheers,
> David
> -----
>
>> I would propose pushing this decision down into the JVM - along roughly this plan:
>>
>> Define a new JVM option: -DatomicLong=[true|false]
>> For any JVM with a 64-bit architecture this would be ignored (or issue a warning if explicitly set to false)
>> For a 32-bit JVM, the default would be false (see below)
>> If true for a 32-bit JVM, then the JVM itself would execute a memory barrier as required to perform atomic load/store of a long or double from/to application memory.
>>
>> A JVM option is suggested because there are probably still many applications running on 32-bit servers, and using a lot of long/double variables, that would suffer a major performance hit if the 32-bit JVM suddenly started implementing atomic load/store operations. Examples: financial models, simulations, weather forecasting. Also many applications may not be multi-threaded and would prefer to eliminate the overhead.
>>
>> Having a default of false preserves the current semantics of a 32-bit JVM.
>>
>> You could also drop the JVM option and have 32-bit JVMs compiled with two flavors: JVM (old semantics) and JVMAtomic (new semantics). This would eliminate any possible runtime overhead and allow the user to invoke the desired version at runtime.
>>
>> Best,
>>
>>
>> John Crowley
>> Westport, CT
>> 203-856-2396
>>
>>
>>
>>
More information about the hotspot-dev
mailing list