[PATCH] remove redundant initialization of volatile fields with default values
David Holmes
david.holmes at oracle.com
Fri Jun 19 13:28:25 UTC 2020
On 19/06/2020 11:25 pm, David Holmes wrote:
> Hi Remi,
>
> On 19/06/2020 6:03 pm, Remi Forax wrote:
>> Hi Sergei,
>> the problem is that you are changing the semantics if there are
>> several fields.
>>
>> By example with the code below, you have the guarantee that the code
>> will print 4 (if it prints something),
>> if you remove the assignment field = false, the code can print 0 or 4.
>>
>> class A {
>> int i = 4;
>> volatile boolean field = false;
>> }
>>
>> thread 1:
>> global = new A()
>>
>> thread 2:
>> var a = global;
>> if (a != null) {
>> System.out.println(a.i);
>> }
>
> Surely you intended to read field to get the volatile read to pair with
> the volatile write of the initializer? Otherwise there is no
> happens-before ordering.
And as Peter points out that may not suffice as you can't distinguish
the default initialization of field with the actual volatile write in
the initializer.
David
> David
>
>> regards,
>> Rémi
>>
>> ----- Mail original -----
>>> De: "Сергей Цыпанов" <sergei.tsypanov at yandex.ru>
>>> À: "core-libs-dev" <core-libs-dev at openjdk.java.net>
>>> Envoyé: Vendredi 19 Juin 2020 06:57:25
>>> Objet: [PATCH] remove redundant initialization of volatile fields
>>> with default values
>>
>>> Hello,
>>>
>>> while investigating an issue I've found out that assignment of
>>> default value to
>>> volatile fields slows down object instantiation.
>>>
>>> Consider the benchmark:
>>>
>>> @State(Scope.Thread)
>>> @OutputTimeUnit(TimeUnit.NANOSECONDS)
>>> @BenchmarkMode(value = Mode.AverageTime)
>>> @Fork(jvmArgsAppend = {"-Xms2g", "-Xmx2g"})
>>> public class VolatileFieldBenchmark {
>>> @Benchmark
>>> public Object explicitInit() {
>>> return new ExplicitInit();
>>> }
>>>
>>> @Benchmark
>>> public Object noInit() {
>>> return new NoInit();
>>> }
>>>
>>> private static class ExplicitInit {
>>> private volatile boolean field = false;
>>> }
>>> private static class NoInit {
>>> private volatile boolean field;
>>> }
>>> }
>>>
>>> This gives the following results as of my machine:
>>>
>>> Benchmark Mode Cnt Score Error Units
>>> VolatileFieldBenchmark.explicitInit avgt 40 11.087 ± 0.140 ns/op
>>> VolatileFieldBenchmark.noInit avgt 40 3.367 ± 0.131 ns/op
>>>
>>>
>>> I've looked into source code of java.base and found out several cases
>>> where the
>>> default value is assigned to volatile field.
>>>
>>> Getting rid of such assignements demonstates improvement as of object
>>> instantiation, e.g. javax.security.auth.Subject:
>>>
>>> Mode Cnt Score Error Units
>>> before avgt 40 35.933 ± 2.647 ns/op
>>> after avgt 40 30.817 ± 2.384 ns/op
>>>
>>> As of testing tier1 and tier2 are both ok after the changes.
>>>
>>> Best regards,
>>> Sergey Tsypanov
More information about the core-libs-dev
mailing list