[9] RFR (S): 8058892: FILL_ARRAYS and ARRAYS are eagely initialized in MethodHandleImpl
Vitaly Davidovich
vitalyd at gmail.com
Thu Oct 2 20:59:19 UTC 2014
Yes sorry, I meant jitter got so much worse. TieredCompilation could be a
source -- I'd try turning it off to see what C2 peak is. I'm guessing your
machine is otherwise quiet when you're running these benchmarks.
On Thu, Oct 2, 2014 at 4:47 PM, Peter Levart <peter.levart at gmail.com> wrote:
>
> 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>
> 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> wrote:
>>
>>>
>>> On 10/02/2014 06:55 PM, Vladimir Ivanov wrote:
>>>
>>>> Small update:
>>>> http://cr.openjdk.java.net/~vlivanov/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 ops/s
>>> j.t.FillArrayTest.fillArrayAlt thrpt 8 90044973.732 8713725
>>> <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/
>>>>> 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
>>>> 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/8682e6ce/attachment-0001.html>
More information about the mlvm-dev
mailing list