[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