RFR (S): JEP-142: Reduce Cache Contention on Specified Fields

Vitaly Davidovich vitalyd at gmail.com
Fri Nov 23 11:26:05 PST 2012


I guess the per @Contended padding specification won't buy much given you
can override the default padding via JVM arg, so scratch that part of my
email. :)

Sent from my phone
On Nov 23, 2012 2:05 PM, "Vitaly Davidovich" <vitalyd at gmail.com> wrote:

> Aleksey,
>
> Have you considered allowing user to specify the padding amount in the
> @Contended constructor? The default can be picked by the VM but may be
> useful to allow overriding it so that someone can get the desired padding
> on some new architecture without upgrading the JVM.
>
> Also, how common is the adjacent line prefetcher today? On archs that
> don't do that, the extra 64 bytes is a waste.  I think you'd really need to
> extract that info from the cpuid if this isn't the dominant type of
> prefetcher.  The extra memory waste may be a bigger issue on embedded
> devices (although even they have quite substantial RAM these days).
>
> Thanks
>
> Sent from my phone
> On Nov 22, 2012 4:35 PM, "Aleksey Shipilev" <aleksey.shipilev at oracle.com>
> wrote:
>
>> Hi,
>>
>> After some internal discussions with Doug Lea, Dave Dice and others, I
>> would like to solicit the initial feedback on the implementation of
>> JEP-142, aka @Contended [1]:
>>   http://openjdk.java.net/jeps/142
>>
>> The webrev for the initial version is here:
>>   http://shipilev.net/pub/jdk/hotspot/contended/webrev-2/
>>
>> Implementation overview. Hotspot code is currently laying out the fields
>> to optimize the memory footprint, rearranging fields freely to both
>> satisfy alignment requirements for fields and making the less gaps
>> possible. We leverage the same infrastructure to exempt specific fields
>> from the packing, and pushing them outside the dense packed block at
>> sparse offsets, naturally making up the appropriate padding.
>>
>> In order to demarcate the specific classes and/or fields eligible for
>> such the padding, we use new @Contended annotation. Runtime discovery of
>> annotations reuses the code John (?) laid out for some of
>> JSR292-specific annotations.
>>
>> The behavior of this annotation is as follows:
>>
>> A. Marking the class as contended:
>>
>>     @Contended
>>     public static class ContendedTest2 {
>>         private Object plainField1;
>>         private Object plainField2;
>>         private Object plainField3;
>>         private Object plainField4;
>>     }
>>
>> ...makes the entire field block to be padded from the both sides:
>> (below is the output of new tracing -XX:+PrintFieldLayout)
>>
>>   TestContended$ContendedTest2: field layout
>>     Entire class is marked contended
>>      @140 --- instance fields start ---
>>      @140 "plainField1" Ljava.lang.Object;
>>      @144 "plainField2" Ljava.lang.Object;
>>      @148 "plainField3" Ljava.lang.Object;
>>      @152 "plainField4" Ljava.lang.Object;
>>      @288 --- instance fields end ---
>>      @288 --- instance ends ---
>>
>> Note that we use 128 bytes, twice the cache line size on most hardware
>> to adjust for adjacent sector prefetchers extending the false sharing
>> collisions to two cache lines.
>>
>> B. Marking the field as contended:
>>
>>     public static class ContendedTest1 {
>>         @Contended
>>         private Object contendedField1;
>>         private Object plainField1;
>>         private Object plainField2;
>>         private Object plainField3;
>>         private Object plainField4;
>>     }
>>
>> ...pushes the field out of dense block and effectively applies padding:
>>
>>    TestContended$ContendedTest1: field layout
>>      @ 12 --- instance fields start ---
>>      @ 12 "plainField1" Ljava.lang.Object;
>>      @ 16 "plainField2" Ljava.lang.Object;
>>      @ 20 "plainField3" Ljava.lang.Object;
>>      @ 24 "plainField4" Ljava.lang.Object;
>>      @156 "contendedField1" Ljava.lang.Object; (contended, group = 0)
>>      @288 --- instance fields end ---
>>      @288 --- instance ends ---
>>
>> C. Marking multiple fields makes each field padded:
>>
>>     public static class ContendedTest4 {
>>         @Contended
>>         private Object contendedField1;
>>
>>         @Contended
>>         private Object contendedField2;
>>
>>         private Object plainField3;
>>         private Object plainField4;
>>     }
>>
>> ...pushes both fields with individual padding for each:
>>
>>    TestContended$ContendedTest4: field layout
>>      @ 12 --- instance fields start ---
>>      @ 12 "plainField3" Ljava.lang.Object;
>>      @ 16 "plainField4" Ljava.lang.Object;
>>      @148 "contendedField1" Ljava.lang.Object; (contended, group = 0)
>>      @280 "contendedField2" Ljava.lang.Object; (contended, group = 0)
>>      @416 --- instance fields end ---
>>      @416 --- instance ends ---
>>
>> *** IV. Contention groups
>>
>> There are cases where you want to separate the *group* of fields that
>> are experiencing contention with everything else but not pairwise. This
>> is the usual thing for some of the code updating two fields at once.
>> While marking both with @Contended would be sufficient, we can optimize
>> the memory footprint by not applying padding between them. In order to
>> demarcate these groups, we have the parameter in the annotation
>> describing the equivalence class for contention group.
>>
>> So that:
>>
>>     public static class ContendedTest5 {
>>         @Contended("updater1")
>>         private Object contendedField1;
>>
>>         @Contended("updater1")
>>         private Object contendedField2;
>>
>>         @Contended("updater2")
>>         private Object contendedField3;
>>
>>         private Object plainField5;
>>         private Object plainField6;
>>     }
>>
>> ...is laid out as:
>>
>>    TestContended$ContendedTest5: field layout
>>      @ 12 --- instance fields start ---
>>      @ 12 "plainField5" Ljava.lang.Object;
>>      @ 16 "plainField6" Ljava.lang.Object;
>>      @148 "contendedField1" Ljava.lang.Object; (contended, group = 12)
>>      @152 "contendedField2" Ljava.lang.Object; (contended, group = 12)
>>      @284 "contendedField3" Ljava.lang.Object; (contended, group = 15)
>>      @416 --- instance fields end ---
>>      @416 --- instance ends ---
>>
>> Note $contendedField1 and $contendedField2 are padded from everything
>> else, but still densely packed with each other.
>>
>> The code is known to work at least on Linux x86-64, tested with a few
>> microtests. The layout of fields without @Contended is not affected, so
>> this is presumably a safe change. I will try to run more tests against
>> this implementation with JPRT, but will appreciate the design, API, and
>> draft implementation review meanwhile...
>>
>> Thanks,
>> Aleksey.
>>
>


More information about the hotspot-dev mailing list