[9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl
Peter Levart
peter.levart at gmail.com
Thu Oct 2 20:47:45 UTC 2014
On 10/02/2014 09:28 PM, Vitaly Davidovich wrote:
> Yes, this is the version I wanted to see (i.e. where the only diff is
> varargs, and not any anything else like array iteration, etc).
> Why did fillCopyLoop() get some much worse than in your prior email
> though?
82050640.406 (+-4055652.247) vs. 82395900.795 (+-2794747.540)
I don't see a noticeable difference (there's a lot of jitter - didn't
turn off tiered compilation).
Regards, Peter
>
>
>
> On Thu, Oct 2, 2014 at 3:12 PM, Peter Levart <peter.levart at gmail.com
> <mailto:peter.levart at gmail.com>> wrote:
>
> Well, if I add the following variant to the mix:
>
> private static void fillWith8Arguments(Object[] a, int pos,
> Object... args) {
> a[pos] = args[0];
> a[pos + 1] = args[1];
> a[pos + 2] = args[2];
> a[pos + 3] = args[3];
> a[pos + 4] = args[4];
> a[pos + 5] = args[5];
> a[pos + 6] = args[6];
> a[pos + 7] = args[7];
> }
>
> private static Object[] fillArrayByHand(
> Integer pos, Object[] a,
> Object a0, Object a1, Object a2, Object a3,
> Object a4, Object a5, Object a6, Object a7
> ) {
> fillWith8Arguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7);
> return a;
> }
>
> @Benchmark
> public Object[] fillByHand() {
> return fillArrayByHand(0, target, a0, a1, a2, a3, a4, a5,
> a6, a7);
> }
>
> The results:
>
> Benchmark Mode Samples Score Score
> error Units
> j.t.FillArrayTest.fillArray thrpt 8 75994667.408
> 4169836.951 ops/s
> j.t.FillArrayTest.fillArrayAlt thrpt 8 142761145.565
> 7127589.095 ops/s
> j.t.FillArrayTest.fillByHand thrpt 8 141206898.861
> 6435932.932 ops/s
> j.t.FillArrayTest.fillCopyLoop thrpt 8 82395900.795
> 2794747.540 ops/s
>
>
> ...show that with fillByHand, varargs array is indeed eliminated.
> But then the "helper" method is not of any help, since it's not
> reusable for different array lengths...
>
>
> Regards, Peter
>
>
> On 10/02/2014 08:54 PM, Peter Levart wrote:
>>
>> On 10/02/2014 08:42 PM, Vitaly Davidovich wrote:
>>>
>>> AFIK, varargs (up to something like 64 args) should be
>>> eliminated by EA. Peter, can you add another jmh test that uses
>>> varargs but doesn't call into System.arraycopy but uses the hand
>>> rolled version like your at method? I'm wondering if that makes
>>> EA not kick in.
>>>
>>
>> Hm, here is a modified benchmark (I also eliminated repeatable
>> allocation of target array):
>>
>>
>> @State(Scope.Benchmark)
>> public class FillArrayTest {
>>
>> private Object
>> a0 = new Object(),
>> a1 = new Object(),
>> a2 = new Object(),
>> a3 = new Object(),
>> a4 = new Object(),
>> a5 = new Object(),
>> a6 = new Object(),
>> a7 = new Object();
>>
>>
>> private Object[] target = new Object[8];
>>
>> private static void fillWithArguments(Object[] a, int pos,
>> Object... args) {
>> System.arraycopy(args, 0, a, pos, args.length);
>> }
>>
>> private static Object[] fillArray(
>> Integer pos, Object[] a,
>> Object a0, Object a1, Object a2, Object a3,
>> Object a4, Object a5, Object a6, Object a7
>> ) {
>> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7);
>> return a;
>> }
>>
>> private static void fillWithArgumentsCopyLoop(Object[] a, int
>> pos, Object... args) {
>> for (int i = 0; i < args.length; i++) {
>> a[i + pos] = args[i];
>> }
>> }
>>
>> private static Object[] fillArrayCopyLoop(
>> Integer pos, Object[] a,
>> Object a0, Object a1, Object a2, Object a3,
>> Object a4, Object a5, Object a6, Object a7
>> ) {
>> fillWithArgumentsCopyLoop(a, pos, a0, a1, a2, a3, a4, a5,
>> a6, a7);
>> return a;
>> }
>>
>> private static Object[] fillArrayAlt(
>> Integer pos, Object[] a,
>> Object a0, Object a1, Object a2, Object a3,
>> Object a4, Object a5, Object a6, Object a7
>> ) {
>> int i = pos;
>> a[i++] = a0;
>> a[i++] = a1;
>> a[i++] = a2;
>> a[i++] = a3;
>> a[i++] = a4;
>> a[i++] = a5;
>> a[i++] = a6;
>> a[i++] = a7;
>> return a;
>> }
>>
>> @Benchmark
>> public Object[] fillArray() {
>> return fillArray(0, target, a0, a1, a2, a3, a4, a5, a6, a7);
>> }
>>
>> @Benchmark
>> public Object[] fillCopyLoop() {
>> return fillArrayCopyLoop(0, target, a0, a1, a2, a3, a4,
>> a5, a6, a7);
>> }
>>
>> @Benchmark
>> public Object[] fillArrayAlt() {
>> return fillArrayAlt(0, target, a0, a1, a2, a3, a4, a5,
>> a6, a7);
>> }
>> }
>>
>>
>>
>> The results:
>>
>>
>> Benchmark Mode Samples Score
>> Score error Units
>> j.t.FillArrayTest.fillArray thrpt 8 76534019.978
>> 3063590.310 ops/s
>> j.t.FillArrayTest.fillArrayAlt thrpt 8 141640280.270
>> 7815152.038 ops/s
>> j.t.FillArrayTest.fillCopyLoop thrpt 8 82050640.406
>> 4055652.247 ops/s
>>
>>
>> The fillCopyLoop seems a little faster. I don't know if this is
>> because of possible elimination of allocation. The fillArrayAlt
>> is still almost 2x as fast.
>>
>> Peter
>>
>>> Sent from my phone
>>>
>>> On Oct 2, 2014 2:34 PM, "Peter Levart" <peter.levart at gmail.com
>>> <mailto:peter.levart at gmail.com>> wrote:
>>>
>>>
>>> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote:
>>>
>>> Small update:
>>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.01/
>>> <http://cr.openjdk.java.net/%7Evlivanov/8058892/webrev.01/>
>>>
>>> Need to reorder initialization sequence in MHI.Lazy.
>>> Initialized FILL_ARRAYS and ARRAYS are required for
>>> later MH lookups.
>>>
>>> Additional testing:
>>> * jck (api/java_lang/invoke)
>>> * jdk/java/lang/invoke, jdk/java/util/streams w/ "-ea
>>> -esa" and COMPILE_THRESHOLD={0,30}
>>>
>>> Best regards,
>>> Vladimir Ivanov
>>>
>>>
>>> Hi Vladimir,
>>>
>>> I have a comment that does not directly pertain to the code
>>> changes (the initialization of arrays) but to the
>>> sub-optimal implementation of "fillArray" methods I noticed
>>> by the way. While it is nice to use varargs "makeArray"
>>> helper method with "array" methods to construct the array,
>>> the same strategy used with "fillWithArguments" in
>>> "fillArray" methods makes a redundant array that is then
>>> copied to target array and discarded. The redundant copying
>>> has a price. Here's a benchmark (Aleksey, please bear with me):
>>>
>>> @State(Scope.Benchmark)
>>> public class FillArrayTest {
>>>
>>> private Object
>>> a0 = new Object(),
>>> a1 = new Object(),
>>> a2 = new Object(),
>>> a3 = new Object(),
>>> a4 = new Object(),
>>> a5 = new Object(),
>>> a6 = new Object(),
>>> a7 = new Object();
>>>
>>>
>>> private static void fillWithArguments(Object[] a, int
>>> pos, Object... args) {
>>> System.arraycopy(args, 0, a, pos, args.length);
>>> }
>>>
>>> private static Object[] fillArray(
>>> Integer pos, Object[] a,
>>> Object a0, Object a1, Object a2, Object a3,
>>> Object a4, Object a5, Object a6, Object a7
>>> ) {
>>> fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5,
>>> a6, a7);
>>> return a;
>>> }
>>>
>>> private static Object[] fillArrayAlt(
>>> Integer pos, Object[] a,
>>> Object a0, Object a1, Object a2, Object a3,
>>> Object a4, Object a5, Object a6, Object a7
>>> ) {
>>> int i = pos;
>>> a[i++] = a0;
>>> a[i++] = a1;
>>> a[i++] = a2;
>>> a[i++] = a3;
>>> a[i++] = a4;
>>> a[i++] = a5;
>>> a[i++] = a6;
>>> a[i++] = a7;
>>> return a;
>>> }
>>>
>>> @Benchmark
>>> public Object[] fillArray() {
>>> return fillArray(0, new Object[8], a0, a1, a2, a3,
>>> a4, a5, a6, a7);
>>> }
>>>
>>> @Benchmark
>>> public Object[] fillArrayAlt() {
>>> return fillArrayAlt(0, new Object[8], a0, a1, a2,
>>> a3, a4, a5, a6, a7);
>>> }
>>> }
>>>
>>>
>>> The results on my i7 with JMH arguments "-i 8 -wi 5 -f 1 -gc
>>> true":
>>>
>>> Benchmark Mode Samples
>>> Score Score error Units
>>> j.t.FillArrayTest.fillArray thrpt 8 48601447.674
>>> 5414853.634 <tel:5414853.634> ops/s
>>> j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732
>>> 8713725 <tel:732%208713725>.735 ops/s
>>>
>>>
>>> So fillArrayAlt is nearly twice as fast...
>>>
>>> Regards, Peter
>>>
>>>
>>>
>>> On 10/2/14, 7:52 PM, Vladimir Ivanov wrote:
>>>
>>> http://cr.openjdk.java.net/~vlivanov/8058892/webrev.00/
>>> <http://cr.openjdk.java.net/%7Evlivanov/8058892/webrev.00/>
>>> https://bugs.openjdk.java.net/browse/JDK-8058892
>>>
>>> Core j.l.i classes are preloaded during VM startup
>>> in order to avoid
>>> possible deadlock when accessing JSR292-related
>>> functionality from
>>> multiple threads. After LF sharing-related changes,
>>> FILL_ARRAYS and
>>> ARRAYS are initialized too early. It affects startup
>>> time & footprint of
>>> applications that don't use JSR292.
>>>
>>> The fix is to move these fields into MHI.Lazy class,
>>> thus delaying their
>>> initialization to the first usage of JSR292 API.
>>>
>>> Testing: failing test, manual (measured HelloWorld
>>> app startup time;
>>> compared -XX:+PrintCompilation logs)
>>>
>>> Best regards,
>>> Vladimir Ivanov
>>>
>>> _______________________________________________
>>> mlvm-dev mailing list
>>> mlvm-dev at openjdk.java.net <mailto:mlvm-dev at openjdk.java.net>
>>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>>>
>>>
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20141002/da829a8b/attachment-0001.html>
More information about the mlvm-dev
mailing list