Re: [External] : Re: Getting back into indy...need a better argument collector!

2021-04-05 Thread Jorn Vernee
Okay, the diagram turned out more crude than intended due to automatic 
email formatting.


See here instead: http://cr.openjdk.java.net/~jvernee/Collector_Diag.txt

Jorn

On 05/04/2021 21:16, Jorn Vernee wrote:
Maybe you could do a fold with  a 'filler' that fills multiple 
elements at a time to reduce the depth.


e.g. declare a bunch of:

void fillArray(Object[] arr, int startPos, Object a0,  Object a1, ...) {
    arr[startPos + 0] = a0;
    arr[startPos + 1] = a1;
    ...
}

With differing arities, and then use a series of collectArguments 
calls to collect the arguments into the final array in chunks (of e.g. 
size 10). Merge all the array parameters together using 
permuteArguments, and then finally stick an array constructor in that 
parameter slot using collectArguments to create the array.


See here a crude diagram:

result( Object,Object,Object,   Object,Object,Object)void
   |  | 
| |  |  |
 arity |  | 
| |  |  |
   |   |  | 
| |  |  |
       V   |  | 
| |  |  |
  Object[]::(int)Object[]    | | | 
|  |  |
    |    startPos=0    |  | 
| |  |  |
    |--||    | |  | 
| |  |  |
        |  |    V    V V  V 
V |  |  |
    |  | fillArray(Object[],int, 
Object,Object,Object)void |  |  |
        | |   | |  
|  |

        |  | startPos=3    | |  |  |
    |  || | |   |  |  |
        |   V V |   V  V  V
    | fillArray(Object[],int,   | 
Object,Object,Object)void

| |   |
        |   |-- collectArguments 
--<---<

    V   V
target(Object[]  )void

Where Object[] and Object can be replaced with sharper types.

Although that would require writing a bunch of hard-coded fillers, one 
for each primitive type and then one for reference types X the chunk 
size you want to support.


HTH,
Jorn

On 02/04/2021 10:00, Charles Oliver Nutter wrote:

First attempt at a workaround seems to be a wash. I rolled back to my
older logic (that does not use a hand-crafted collector method) to
come up with a pure-MethodHandle workaround for asCollector. I came up
with this (using InvokeBinder):

```
MethodHandle constructArray = Binder.from(arrayType, Object[].class)
 .fold(MethodHandles.arrayLength(Object[].class))
 .dropLast()
 .newArray();

MethodHandle transmuteArray = Binder.from(arrayType, Object[].class)
 .fold(constructArray)
 .appendInts(0, 0, count)
 .permute(1, 2, 0, 3, 4)
 .cast(ARRAYCOPY.type().changeReturnType(arrayType))
 .fold(ARRAYCOPY)
 .permute(2)
 .cast(arrayType, arrayType)
 .identity();

MethodHandle collector = transmuteArray.asCollector(Object[].class,
count).asType(source.dropParameterTypes(0,
index).changeReturnType(arrayType));

return MethodHandles.collectArguments(target, index, collector);
```

Hopefully this is mostly readable. Basically I craft a chain of
handles that uses the normal Object[] collector and then simulates
what the pre-Jorn asCollector does: allocate the actual array we want
and arraycopy everything over. I figured this would be worth a try
since Jorn's comments on the PR hinted at the intermediate Object[]
going away for some collect forms. Unfortunately, reproducing the old
asCollector using MethodHandles does not appear to work any better...
or at least it still pales compared to a collector function.

I am open to suggestions because my next attempt will probably be to
chain a series of folds together that populate the target array
directly, but it will be array.length deep. Not ideal and not a good
general solution.

On Thu, Apr 1, 2021 at 6:44 PM Charles Oliver Nutter
 wrote:
Very nice! I will have a look at the pull request and perhaps it 
will lead me to a short-term work around as well.


On Thu, Apr 1, 2021, 12:04 Jorn Vernee  wrote:

Hi Charlie,

(Sorry for replying out of line like this, but I'm not currently
subscribed to the mlvm-dev mailing list, so I could not reply to your
earlier email thread directly.)

I have fixed the performance issue with asCollector you reported [1],
and with the patch the performance should be the same/similar for any
array type (as well as fixing a related issue with collectors that 
take

more than 10 arguments). The patch is out for review here:

Re: [External] : Re: Getting back into indy...need a better argument collector!

2021-04-05 Thread Jorn Vernee
Maybe you could do a fold with  a 'filler' that fills multiple elements 
at a time to reduce the depth.


e.g. declare a bunch of:

void fillArray(Object[] arr, int startPos, Object a0,  Object a1, ...) {
    arr[startPos + 0] = a0;
    arr[startPos + 1] = a1;
    ...
}

With differing arities, and then use a series of collectArguments calls 
to collect the arguments into the final array in chunks (of e.g. size 
10). Merge all the array parameters together using permuteArguments, and 
then finally stick an array constructor in that parameter slot using 
collectArguments to create the array.


See here a crude diagram:

result( Object,Object,Object,   Object,Object,Object)void
   |  | 
| |  |  |
 arity |  | 
| |  |  |
   |   |  | 
| |  |  |
       V   |  | 
| |  |  |
  Object[]::(int)Object[]    | |  
| |  |  |
    |    startPos=0    |  | 
| |  |  |
    |--||    | |  | 
| |  |  |
        |  |    V    V V  V 
V |  |  |
    |  | fillArray(Object[],int, 
Object,Object,Object)void |  |  |
        | |   | |  
|  |
        |  | startPos=3    |   |  
|  |
    |  || | |   
|  |  |
        |   V V |   
V  V  V
    | fillArray(Object[],int,   | 
Object,Object,Object)void

| |   |
        |   |-- collectArguments 
--<---<

    V   V
target(Object[]  )void

Where Object[] and Object can be replaced with sharper types.

Although that would require writing a bunch of hard-coded fillers, one 
for each primitive type and then one for reference types X the chunk 
size you want to support.


HTH,
Jorn

On 02/04/2021 10:00, Charles Oliver Nutter wrote:

First attempt at a workaround seems to be a wash. I rolled back to my
older logic (that does not use a hand-crafted collector method) to
come up with a pure-MethodHandle workaround for asCollector. I came up
with this (using InvokeBinder):

```
MethodHandle constructArray = Binder.from(arrayType, Object[].class)
 .fold(MethodHandles.arrayLength(Object[].class))
 .dropLast()
 .newArray();

MethodHandle transmuteArray = Binder.from(arrayType, Object[].class)
 .fold(constructArray)
 .appendInts(0, 0, count)
 .permute(1, 2, 0, 3, 4)
 .cast(ARRAYCOPY.type().changeReturnType(arrayType))
 .fold(ARRAYCOPY)
 .permute(2)
 .cast(arrayType, arrayType)
 .identity();

MethodHandle collector = transmuteArray.asCollector(Object[].class,
count).asType(source.dropParameterTypes(0,
index).changeReturnType(arrayType));

return MethodHandles.collectArguments(target, index, collector);
```

Hopefully this is mostly readable. Basically I craft a chain of
handles that uses the normal Object[] collector and then simulates
what the pre-Jorn asCollector does: allocate the actual array we want
and arraycopy everything over. I figured this would be worth a try
since Jorn's comments on the PR hinted at the intermediate Object[]
going away for some collect forms. Unfortunately, reproducing the old
asCollector using MethodHandles does not appear to work any better...
or at least it still pales compared to a collector function.

I am open to suggestions because my next attempt will probably be to
chain a series of folds together that populate the target array
directly, but it will be array.length deep. Not ideal and not a good
general solution.

On Thu, Apr 1, 2021 at 6:44 PM Charles Oliver Nutter
 wrote:

Very nice! I will have a look at the pull request and perhaps it will lead me 
to a short-term work around as well.

On Thu, Apr 1, 2021, 12:04 Jorn Vernee  wrote:

Hi Charlie,

(Sorry for replying out of line like this, but I'm not currently
subscribed to the mlvm-dev mailing list, so I could not reply to your
earlier email thread directly.)

I have fixed the performance issue with asCollector you reported [1],
and with the patch the performance should be the same/similar for any
array type (as well as fixing a related issue with collectors that take
more than 10 arguments). The patch is out for review here:
https://urldefense.com/v3/__https://github.com/openjdk/jdk/pull/3306__;!!GqivPVa7Brio!NeZJUPlqKG3_Z1yUBVS5cX1Gtz0pQMuFcTiR0PMhz42KSgmJpMNj8zkru_YUYkM-$

Cheers,
Jorn

[1] : 

Re: Getting back into indy...need a better argument collector!

2021-04-02 Thread Charles Oliver Nutter
First attempt at a workaround seems to be a wash. I rolled back to my
older logic (that does not use a hand-crafted collector method) to
come up with a pure-MethodHandle workaround for asCollector. I came up
with this (using InvokeBinder):

```
MethodHandle constructArray = Binder.from(arrayType, Object[].class)
.fold(MethodHandles.arrayLength(Object[].class))
.dropLast()
.newArray();

MethodHandle transmuteArray = Binder.from(arrayType, Object[].class)
.fold(constructArray)
.appendInts(0, 0, count)
.permute(1, 2, 0, 3, 4)
.cast(ARRAYCOPY.type().changeReturnType(arrayType))
.fold(ARRAYCOPY)
.permute(2)
.cast(arrayType, arrayType)
.identity();

MethodHandle collector = transmuteArray.asCollector(Object[].class,
count).asType(source.dropParameterTypes(0,
index).changeReturnType(arrayType));

return MethodHandles.collectArguments(target, index, collector);
```

Hopefully this is mostly readable. Basically I craft a chain of
handles that uses the normal Object[] collector and then simulates
what the pre-Jorn asCollector does: allocate the actual array we want
and arraycopy everything over. I figured this would be worth a try
since Jorn's comments on the PR hinted at the intermediate Object[]
going away for some collect forms. Unfortunately, reproducing the old
asCollector using MethodHandles does not appear to work any better...
or at least it still pales compared to a collector function.

I am open to suggestions because my next attempt will probably be to
chain a series of folds together that populate the target array
directly, but it will be array.length deep. Not ideal and not a good
general solution.

On Thu, Apr 1, 2021 at 6:44 PM Charles Oliver Nutter
 wrote:
>
> Very nice! I will have a look at the pull request and perhaps it will lead me 
> to a short-term work around as well.
>
> On Thu, Apr 1, 2021, 12:04 Jorn Vernee  wrote:
>>
>> Hi Charlie,
>>
>> (Sorry for replying out of line like this, but I'm not currently
>> subscribed to the mlvm-dev mailing list, so I could not reply to your
>> earlier email thread directly.)
>>
>> I have fixed the performance issue with asCollector you reported [1],
>> and with the patch the performance should be the same/similar for any
>> array type (as well as fixing a related issue with collectors that take
>> more than 10 arguments). The patch is out for review here:
>> https://github.com/openjdk/jdk/pull/3306
>>
>> Cheers,
>> Jorn
>>
>> [1] : https://bugs.openjdk.java.net/browse/JDK-8264288
>>
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2021-04-01 Thread Charles Oliver Nutter
Very nice! I will have a look at the pull request and perhaps it will lead
me to a short-term work around as well.

On Thu, Apr 1, 2021, 12:04 Jorn Vernee  wrote:

> Hi Charlie,
>
> (Sorry for replying out of line like this, but I'm not currently
> subscribed to the mlvm-dev mailing list, so I could not reply to your
> earlier email thread directly.)
>
> I have fixed the performance issue with asCollector you reported [1],
> and with the patch the performance should be the same/similar for any
> array type (as well as fixing a related issue with collectors that take
> more than 10 arguments). The patch is out for review here:
> https://github.com/openjdk/jdk/pull/3306
>
> Cheers,
> Jorn
>
> [1] : https://bugs.openjdk.java.net/browse/JDK-8264288
>
>
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2021-03-26 Thread Charles Oliver Nutter
Thanks Paul! I am moving forward with my JRuby PRs but if I can help
in any way let me know.

I am especially interested in whether there might be some workaround
rather than having to write my own custom argument boxing collectors.
Will try to poke around at other combinations of handles and see what
I can come up with.

- Charlie

On Fri, Mar 26, 2021 at 11:20 AM Paul Sandoz  wrote:
>
> Hi Charlie,
>
> Thanks for the details. I quickly logged:
>
>   https://bugs.openjdk.java.net/browse/JDK-8264288
>
> I don’t have time to dive into the details right now. Perhaps next week, or 
> hopefully someone else can.
>
> Paul.
>
> > On Mar 25, 2021, at 9:25 PM, Charles Oliver Nutter  
> > wrote:
> >
> > JRuby branch with changes to use our own collector methods:
> > https://github.com/jruby/jruby/pull/6630
> >
> > InvokeBinder 1.2 added collect(index, type, collector) that calls
> > MethodHandles.collectArguments:
> > https://github.com/headius/invokebinder/commit/9650de07715c6e15a8ca4029c40ea5ede9d5c4c9
> >
> > A build of JRuby from the branch (or from jruby-9.2 branch or master
> > once it is merged) compared with JRuby 9.2.16.0 should show the issue.
> > Benchmark included in the PR above.
> >
> > On Thu, Mar 25, 2021 at 8:43 PM Charles Oliver Nutter
> >  wrote:
> >>
> >> After experimenting with MethodHandles.collectArguments (given a
> >> hand-written collector function) versus my own logic (using folds and
> >> permutes to call my collector), I can confirm that both are roughly
> >> equivalent and better than MethodHandle.asCollector.
> >>
> >> The benchmark linked below calls a lightweight core Ruby method
> >> (Array#dig) that only accepts an IRubyObject[] (so all arities must
> >> box). The performance of collectArguments is substantially better than
> >> asCollector.
> >>
> >> https://gist.github.com/headius/28343b8c393e76c717314af57089848d
> >>
> >> I do not believe this should be so. The logic for asCollector should
> >> be able to gather up Object subtypes into an Object[] subtype without
> >> an intermediate array or extra copying.
> >>
> >> On Thu, Mar 25, 2021 at 7:39 PM Charles Oliver Nutter
> >>  wrote:
> >>>
> >>> Well it only took me five years to circle back to this but I can
> >>> confirm it is just as bad now as it ever was. And it is definitely due
> >>> to collecting a single type.
> >>>
> >>> I will provide whatever folks need to investigate but it is pretty
> >>> straightforward. When asking for asCollector of a non-Object[] type,
> >>> the implementation will first gather arguments into an Object[], and
> >>> then create a copy of that array as the correct type. So two arrays
> >>> are created, values are copied twice.
> >>>
> >>> I can see this quite clearly in the assembly after letting things
> >>> optimize. A new Object[] is created and populated, and then a second
> >>> array of the correct type is created followed by an arraycopy
> >>> operation.
> >>>
> >>> I am once again backing off using asCollector directly to instead
> >>> provide my own array-construction collector.
> >>>
> >>> Should be easy to reproduce the perf issues simply by doing an
> >>> asCollector that results in some subtype of Object[].
> >>>
> >>> On Thu, Jan 14, 2016 at 8:18 PM Charles Oliver Nutter
> >>>  wrote:
> 
>  Thanks Duncan. I will try to look under the covers this evening.
> 
>  - Charlie (mobile)
> 
>  On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" 
>   wrote:
> >
> > On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE 
> > Energy
> > Management)"  > duncan.macgre...@ge.com> wrote:
> >
> >> On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
> >> 
> >> wrote:
> >> ...
> >>> With asCollector: 16-17s per iteration
> >>>
> >>> With hand-written array construction: 7-8s per iteration
> >>>
> >>> A sampling profile only shows my Ruby code as the top items, and an
> >>> allocation trace shows Object[] as the number one object being
> >>> created...not IRubyObject[]. Could that be the reason it's slower?
> >>> Some type trickery messing with optimization?
> >>>
> >>> This is very unfortunate because there's no other general-purpose way
> >>> to collect arguments in a handle chain.
> >>
> >> I haven¹t done any comparative benchmarks in that area for a while, but
> >> collecting a single argument is a pretty common pattern in the Magik 
> >> code,
> >> and I had not seen any substantial difference when we last touched that
> >> area. However we are collecting to plain Object[] so it might be that 
> >> is
> >> the reason for the difference. If I¹ve got time later this week I¹ll do
> >> some experimenting and check what the current situation is.
> >
> > Okay, I’ve now had a chance to try this in with our language benchmarks
> > and can’t see any significant difference between a hand crafted method 
> 

Re: Getting back into indy...need a better argument collector!

2021-03-26 Thread Paul Sandoz
Hi Charlie,

Thanks for the details. I quickly logged:

  https://bugs.openjdk.java.net/browse/JDK-8264288

I don’t have time to dive into the details right now. Perhaps next week, or 
hopefully someone else can.

Paul.

> On Mar 25, 2021, at 9:25 PM, Charles Oliver Nutter  
> wrote:
> 
> JRuby branch with changes to use our own collector methods:
> https://github.com/jruby/jruby/pull/6630
> 
> InvokeBinder 1.2 added collect(index, type, collector) that calls
> MethodHandles.collectArguments:
> https://github.com/headius/invokebinder/commit/9650de07715c6e15a8ca4029c40ea5ede9d5c4c9
> 
> A build of JRuby from the branch (or from jruby-9.2 branch or master
> once it is merged) compared with JRuby 9.2.16.0 should show the issue.
> Benchmark included in the PR above.
> 
> On Thu, Mar 25, 2021 at 8:43 PM Charles Oliver Nutter
>  wrote:
>> 
>> After experimenting with MethodHandles.collectArguments (given a
>> hand-written collector function) versus my own logic (using folds and
>> permutes to call my collector), I can confirm that both are roughly
>> equivalent and better than MethodHandle.asCollector.
>> 
>> The benchmark linked below calls a lightweight core Ruby method
>> (Array#dig) that only accepts an IRubyObject[] (so all arities must
>> box). The performance of collectArguments is substantially better than
>> asCollector.
>> 
>> https://gist.github.com/headius/28343b8c393e76c717314af57089848d
>> 
>> I do not believe this should be so. The logic for asCollector should
>> be able to gather up Object subtypes into an Object[] subtype without
>> an intermediate array or extra copying.
>> 
>> On Thu, Mar 25, 2021 at 7:39 PM Charles Oliver Nutter
>>  wrote:
>>> 
>>> Well it only took me five years to circle back to this but I can
>>> confirm it is just as bad now as it ever was. And it is definitely due
>>> to collecting a single type.
>>> 
>>> I will provide whatever folks need to investigate but it is pretty
>>> straightforward. When asking for asCollector of a non-Object[] type,
>>> the implementation will first gather arguments into an Object[], and
>>> then create a copy of that array as the correct type. So two arrays
>>> are created, values are copied twice.
>>> 
>>> I can see this quite clearly in the assembly after letting things
>>> optimize. A new Object[] is created and populated, and then a second
>>> array of the correct type is created followed by an arraycopy
>>> operation.
>>> 
>>> I am once again backing off using asCollector directly to instead
>>> provide my own array-construction collector.
>>> 
>>> Should be easy to reproduce the perf issues simply by doing an
>>> asCollector that results in some subtype of Object[].
>>> 
>>> On Thu, Jan 14, 2016 at 8:18 PM Charles Oliver Nutter
>>>  wrote:
 
 Thanks Duncan. I will try to look under the covers this evening.
 
 - Charlie (mobile)
 
 On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" 
  wrote:
> 
> On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
> Management)"  duncan.macgre...@ge.com> wrote:
> 
>> On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
>> 
>> wrote:
>> ...
>>> With asCollector: 16-17s per iteration
>>> 
>>> With hand-written array construction: 7-8s per iteration
>>> 
>>> A sampling profile only shows my Ruby code as the top items, and an
>>> allocation trace shows Object[] as the number one object being
>>> created...not IRubyObject[]. Could that be the reason it's slower?
>>> Some type trickery messing with optimization?
>>> 
>>> This is very unfortunate because there's no other general-purpose way
>>> to collect arguments in a handle chain.
>> 
>> I haven¹t done any comparative benchmarks in that area for a while, but
>> collecting a single argument is a pretty common pattern in the Magik 
>> code,
>> and I had not seen any substantial difference when we last touched that
>> area. However we are collecting to plain Object[] so it might be that is
>> the reason for the difference. If I¹ve got time later this week I¹ll do
>> some experimenting and check what the current situation is.
> 
> Okay, I’ve now had a chance to try this in with our language benchmarks
> and can’t see any significant difference between a hand crafted method and
> asCOllector, but we are dealing with Object and Object[], so it might be
> something to do with additional casting.
> 
> Duncan.
> 
> ___
> mlvm-dev mailing list
> mlvm-dev@openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
> ___
> mlvm-dev mailing list
> mlvm-dev@openjdk.java.net
> https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net

Re: Getting back into indy...need a better argument collector!

2021-03-25 Thread Charles Oliver Nutter
JRuby branch with changes to use our own collector methods:
https://github.com/jruby/jruby/pull/6630

InvokeBinder 1.2 added collect(index, type, collector) that calls
MethodHandles.collectArguments:
https://github.com/headius/invokebinder/commit/9650de07715c6e15a8ca4029c40ea5ede9d5c4c9

A build of JRuby from the branch (or from jruby-9.2 branch or master
once it is merged) compared with JRuby 9.2.16.0 should show the issue.
Benchmark included in the PR above.

On Thu, Mar 25, 2021 at 8:43 PM Charles Oliver Nutter
 wrote:
>
> After experimenting with MethodHandles.collectArguments (given a
> hand-written collector function) versus my own logic (using folds and
> permutes to call my collector), I can confirm that both are roughly
> equivalent and better than MethodHandle.asCollector.
>
> The benchmark linked below calls a lightweight core Ruby method
> (Array#dig) that only accepts an IRubyObject[] (so all arities must
> box). The performance of collectArguments is substantially better than
> asCollector.
>
> https://gist.github.com/headius/28343b8c393e76c717314af57089848d
>
> I do not believe this should be so. The logic for asCollector should
> be able to gather up Object subtypes into an Object[] subtype without
> an intermediate array or extra copying.
>
> On Thu, Mar 25, 2021 at 7:39 PM Charles Oliver Nutter
>  wrote:
> >
> > Well it only took me five years to circle back to this but I can
> > confirm it is just as bad now as it ever was. And it is definitely due
> > to collecting a single type.
> >
> > I will provide whatever folks need to investigate but it is pretty
> > straightforward. When asking for asCollector of a non-Object[] type,
> > the implementation will first gather arguments into an Object[], and
> > then create a copy of that array as the correct type. So two arrays
> > are created, values are copied twice.
> >
> > I can see this quite clearly in the assembly after letting things
> > optimize. A new Object[] is created and populated, and then a second
> > array of the correct type is created followed by an arraycopy
> > operation.
> >
> > I am once again backing off using asCollector directly to instead
> > provide my own array-construction collector.
> >
> > Should be easy to reproduce the perf issues simply by doing an
> > asCollector that results in some subtype of Object[].
> >
> > On Thu, Jan 14, 2016 at 8:18 PM Charles Oliver Nutter
> >  wrote:
> > >
> > > Thanks Duncan. I will try to look under the covers this evening.
> > >
> > > - Charlie (mobile)
> > >
> > > On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" 
> > >  wrote:
> > >>
> > >> On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
> > >> Management)"  > >> duncan.macgre...@ge.com> wrote:
> > >>
> > >> >On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
> > >> >
> > >> >wrote:
> > >> >...
> > >> >>With asCollector: 16-17s per iteration
> > >> >>
> > >> >>With hand-written array construction: 7-8s per iteration
> > >> >>
> > >> >>A sampling profile only shows my Ruby code as the top items, and an
> > >> >>allocation trace shows Object[] as the number one object being
> > >> >>created...not IRubyObject[]. Could that be the reason it's slower?
> > >> >>Some type trickery messing with optimization?
> > >> >>
> > >> >>This is very unfortunate because there's no other general-purpose way
> > >> >>to collect arguments in a handle chain.
> > >> >
> > >> >I haven¹t done any comparative benchmarks in that area for a while, but
> > >> >collecting a single argument is a pretty common pattern in the Magik 
> > >> >code,
> > >> >and I had not seen any substantial difference when we last touched that
> > >> >area. However we are collecting to plain Object[] so it might be that is
> > >> >the reason for the difference. If I¹ve got time later this week I¹ll do
> > >> >some experimenting and check what the current situation is.
> > >>
> > >> Okay, I’ve now had a chance to try this in with our language benchmarks
> > >> and can’t see any significant difference between a hand crafted method 
> > >> and
> > >> asCOllector, but we are dealing with Object and Object[], so it might be
> > >> something to do with additional casting.
> > >>
> > >> Duncan.
> > >>
> > >> ___
> > >> mlvm-dev mailing list
> > >> mlvm-dev@openjdk.java.net
> > >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2021-03-25 Thread Charles Oliver Nutter
After experimenting with MethodHandles.collectArguments (given a
hand-written collector function) versus my own logic (using folds and
permutes to call my collector), I can confirm that both are roughly
equivalent and better than MethodHandle.asCollector.

The benchmark linked below calls a lightweight core Ruby method
(Array#dig) that only accepts an IRubyObject[] (so all arities must
box). The performance of collectArguments is substantially better than
asCollector.

https://gist.github.com/headius/28343b8c393e76c717314af57089848d

I do not believe this should be so. The logic for asCollector should
be able to gather up Object subtypes into an Object[] subtype without
an intermediate array or extra copying.

On Thu, Mar 25, 2021 at 7:39 PM Charles Oliver Nutter
 wrote:
>
> Well it only took me five years to circle back to this but I can
> confirm it is just as bad now as it ever was. And it is definitely due
> to collecting a single type.
>
> I will provide whatever folks need to investigate but it is pretty
> straightforward. When asking for asCollector of a non-Object[] type,
> the implementation will first gather arguments into an Object[], and
> then create a copy of that array as the correct type. So two arrays
> are created, values are copied twice.
>
> I can see this quite clearly in the assembly after letting things
> optimize. A new Object[] is created and populated, and then a second
> array of the correct type is created followed by an arraycopy
> operation.
>
> I am once again backing off using asCollector directly to instead
> provide my own array-construction collector.
>
> Should be easy to reproduce the perf issues simply by doing an
> asCollector that results in some subtype of Object[].
>
> On Thu, Jan 14, 2016 at 8:18 PM Charles Oliver Nutter
>  wrote:
> >
> > Thanks Duncan. I will try to look under the covers this evening.
> >
> > - Charlie (mobile)
> >
> > On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" 
> >  wrote:
> >>
> >> On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
> >> Management)"  >> duncan.macgre...@ge.com> wrote:
> >>
> >> >On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
> >> >
> >> >wrote:
> >> >...
> >> >>With asCollector: 16-17s per iteration
> >> >>
> >> >>With hand-written array construction: 7-8s per iteration
> >> >>
> >> >>A sampling profile only shows my Ruby code as the top items, and an
> >> >>allocation trace shows Object[] as the number one object being
> >> >>created...not IRubyObject[]. Could that be the reason it's slower?
> >> >>Some type trickery messing with optimization?
> >> >>
> >> >>This is very unfortunate because there's no other general-purpose way
> >> >>to collect arguments in a handle chain.
> >> >
> >> >I haven¹t done any comparative benchmarks in that area for a while, but
> >> >collecting a single argument is a pretty common pattern in the Magik code,
> >> >and I had not seen any substantial difference when we last touched that
> >> >area. However we are collecting to plain Object[] so it might be that is
> >> >the reason for the difference. If I¹ve got time later this week I¹ll do
> >> >some experimenting and check what the current situation is.
> >>
> >> Okay, I’ve now had a chance to try this in with our language benchmarks
> >> and can’t see any significant difference between a hand crafted method and
> >> asCOllector, but we are dealing with Object and Object[], so it might be
> >> something to do with additional casting.
> >>
> >> Duncan.
> >>
> >> ___
> >> mlvm-dev mailing list
> >> mlvm-dev@openjdk.java.net
> >> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2021-03-25 Thread Charles Oliver Nutter
Well it only took me five years to circle back to this but I can
confirm it is just as bad now as it ever was. And it is definitely due
to collecting a single type.

I will provide whatever folks need to investigate but it is pretty
straightforward. When asking for asCollector of a non-Object[] type,
the implementation will first gather arguments into an Object[], and
then create a copy of that array as the correct type. So two arrays
are created, values are copied twice.

I can see this quite clearly in the assembly after letting things
optimize. A new Object[] is created and populated, and then a second
array of the correct type is created followed by an arraycopy
operation.

I am once again backing off using asCollector directly to instead
provide my own array-construction collector.

Should be easy to reproduce the perf issues simply by doing an
asCollector that results in some subtype of Object[].

On Thu, Jan 14, 2016 at 8:18 PM Charles Oliver Nutter
 wrote:
>
> Thanks Duncan. I will try to look under the covers this evening.
>
> - Charlie (mobile)
>
> On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" 
>  wrote:
>>
>> On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
>> Management)" > duncan.macgre...@ge.com> wrote:
>>
>> >On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
>> >
>> >wrote:
>> >...
>> >>With asCollector: 16-17s per iteration
>> >>
>> >>With hand-written array construction: 7-8s per iteration
>> >>
>> >>A sampling profile only shows my Ruby code as the top items, and an
>> >>allocation trace shows Object[] as the number one object being
>> >>created...not IRubyObject[]. Could that be the reason it's slower?
>> >>Some type trickery messing with optimization?
>> >>
>> >>This is very unfortunate because there's no other general-purpose way
>> >>to collect arguments in a handle chain.
>> >
>> >I haven¹t done any comparative benchmarks in that area for a while, but
>> >collecting a single argument is a pretty common pattern in the Magik code,
>> >and I had not seen any substantial difference when we last touched that
>> >area. However we are collecting to plain Object[] so it might be that is
>> >the reason for the difference. If I¹ve got time later this week I¹ll do
>> >some experimenting and check what the current situation is.
>>
>> Okay, I’ve now had a chance to try this in with our language benchmarks
>> and can’t see any significant difference between a hand crafted method and
>> asCOllector, but we are dealing with Object and Object[], so it might be
>> something to do with additional casting.
>>
>> Duncan.
>>
>> ___
>> mlvm-dev mailing list
>> mlvm-dev@openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
https://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2016-01-14 Thread Charles Oliver Nutter
Thanks Duncan. I will try to look under the covers this evening.

- Charlie (mobile)
On Jan 14, 2016 14:39, "MacGregor, Duncan (GE Energy Management)" <
duncan.macgre...@ge.com> wrote:

> On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
> Management)"  duncan.macgre...@ge.com> wrote:
>
> >On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
> >
> >wrote:
> >...
> >>With asCollector: 16-17s per iteration
> >>
> >>With hand-written array construction: 7-8s per iteration
> >>
> >>A sampling profile only shows my Ruby code as the top items, and an
> >>allocation trace shows Object[] as the number one object being
> >>created...not IRubyObject[]. Could that be the reason it's slower?
> >>Some type trickery messing with optimization?
> >>
> >>This is very unfortunate because there's no other general-purpose way
> >>to collect arguments in a handle chain.
> >
> >I haven¹t done any comparative benchmarks in that area for a while, but
> >collecting a single argument is a pretty common pattern in the Magik code,
> >and I had not seen any substantial difference when we last touched that
> >area. However we are collecting to plain Object[] so it might be that is
> >the reason for the difference. If I¹ve got time later this week I¹ll do
> >some experimenting and check what the current situation is.
>
> Okay, I’ve now had a chance to try this in with our language benchmarks
> and can’t see any significant difference between a hand crafted method and
> asCOllector, but we are dealing with Object and Object[], so it might be
> something to do with additional casting.
>
> Duncan.
>
> ___
> mlvm-dev mailing list
> mlvm-dev@openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
>
___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2016-01-14 Thread MacGregor, Duncan (GE Energy Management)
On 11/01/2016, 11:27, "mlvm-dev on behalf of MacGregor, Duncan (GE Energy
Management)"  wrote:

>On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
>
>wrote:
>...
>>With asCollector: 16-17s per iteration
>>
>>With hand-written array construction: 7-8s per iteration
>>
>>A sampling profile only shows my Ruby code as the top items, and an
>>allocation trace shows Object[] as the number one object being
>>created...not IRubyObject[]. Could that be the reason it's slower?
>>Some type trickery messing with optimization?
>>
>>This is very unfortunate because there's no other general-purpose way
>>to collect arguments in a handle chain.
>
>I haven¹t done any comparative benchmarks in that area for a while, but
>collecting a single argument is a pretty common pattern in the Magik code,
>and I had not seen any substantial difference when we last touched that
>area. However we are collecting to plain Object[] so it might be that is
>the reason for the difference. If I¹ve got time later this week I¹ll do
>some experimenting and check what the current situation is.

Okay, I’ve now had a chance to try this in with our language benchmarks
and can’t see any significant difference between a hand crafted method and
asCOllector, but we are dealing with Object and Object[], so it might be
something to do with additional casting.

Duncan.

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev


Re: Getting back into indy...need a better argument collector!

2016-01-11 Thread MacGregor, Duncan (GE Energy Management)
On 11/01/2016, 03:16, "mlvm-dev on behalf of Charles Oliver Nutter"
 wrote:
...
>With asCollector: 16-17s per iteration
>
>With hand-written array construction: 7-8s per iteration
>
>A sampling profile only shows my Ruby code as the top items, and an
>allocation trace shows Object[] as the number one object being
>created...not IRubyObject[]. Could that be the reason it's slower?
>Some type trickery messing with optimization?
>
>This is very unfortunate because there's no other general-purpose way
>to collect arguments in a handle chain.

I haven¹t done any comparative benchmarks in that area for a while, but
collecting a single argument is a pretty common pattern in the Magik code,
and I had not seen any substantial difference when we last touched that
area. However we are collecting to plain Object[] so it might be that is
the reason for the difference. If I¹ve got time later this week I¹ll do
some experimenting and check what the current situation is.

Duncan.

___
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev