RFR: 8254146: Avoid unnecessary volatile write on new AtomicBoolean(false)

Сергей Цыпанов github.com+10835776+stsypanov at openjdk.java.net
Thu Oct 15 12:12:18 UTC 2020


On Thu, 15 Oct 2020 10:37:01 GMT, Claes Redestad <redestad at openjdk.org> wrote:

>> I appologise for writing this to already closed issue, but Christoph's approach seems to be applicable for at least
>> `AtomicInteger` and `AtomicLong`, because they are often explicitly zeroed at creation time (see one of my previous PRs
>> https://github.com/spring-projects/spring-framework/pull/25846) and there we have the same effect as in
>> `AtomicBoolean`: @State(Scope.Thread) @OutputTimeUnit(TimeUnit.NANOSECONDS) @BenchmarkMode(value = Mode.AverageTime)
>> public class AtomicBenchmark {
>>   @Benchmark
>>   public Object defaultValue() {
>>     return new AtomicInteger();
>>   }
>>   @Benchmark
>>   public Object explicitValue() {
>>     return new AtomicInteger(0);
>>   }
>> }
>> Semantically both new AtomicInteger() and new AtomicInteger(0) are the same, but explicitValue() is much slower:
>> Benchmark                      Mode  Cnt   Score   Error  Units
>> AtomicBenchmark.defaultValue   avgt   30   4.778 ± 0.403  ns/op
>> AtomicBenchmark.explicitValue  avgt   30  11.846 ± 0.273  ns/op
>> So the same pattern as we used here could be applied for `AtomicInteger`:
>> public AtomicInteger(int initialValue) {
>>   if (initialValue != 0 {
>>     value = initialValue;
>>   }
>> }
>> What do you think?
>
>> What do you think?
> 
> For `AtomicBoolean`, this optimization piggy-backed on an existing test, just rewriting it so that no action is taken
> when none is needed. So it's never a pessimization, and even improves bytecode size marginally. So it'll be a marginal
> gain even if the current overhead of writing to a volatile field in a constructor is removed/reduced.   For
> `AtomicInteger/-Long`, we'd have to add a test that's not there, so we'd pessimize non-zero cases by adding some
> bytecode and a branch to remove the overhead. An overhead that can already be avoided by calling the empty constructor
> instead. So I think it's questionable to do this.  In the short term we could consider a point fix to replace existing
> use of `new AtomicInteger/-Long(0)` with `new AtomicInteger/-Long()`, but in the long term we should really try and
> optimize our JITs so that writing to a volatile field in constructors can be made cheaper.

@cl4es , @dreis2211 thanks for explanation!

-------------

PR: https://git.openjdk.java.net/jdk/pull/510


More information about the core-libs-dev mailing list