Memory Segment efficient array handling

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Thu Apr 1 10:07:19 UTC 2021


On 01/04/2021 03:08, Ty Young wrote:
> It would probably be more efficient to skip the whole 
> MemorySegment.ofArray() and MemorySegment.copyFrom bits and just do:
>
>
> public static void arrayCopy(int[] javaArray, int index, MemorySegment 
> destination, int offset)
> {
>      for(int i = index; i < javaArray.length; i++)
>          MemoryAccess.setIntAtIndex(destination, offset + i, 
> javaArray[i]);
> }
>
>
> Because you already have the array of ints in a standard Java array, 
> If you do what you're doing, you're creating on-heap objects that are 
> then GC'd right away and wasting time slicing segments to each 
> element's exact size to copy the data. Slicing should really be 
> avoided when possible. My JavaFX application has to slice 
> MemorySegments and it's one of the biggest sources of on-heap 
> allocations according to Java Mission Control.

I beg to differ - it all depends on the size of the array/slice. For 
small sizes, a loop win; for bigger sizes, bulk copy wins (which is why 
System.arrayCopy doesn't - always - do a loop).

Maurizio

>
>
> That said, maybe it wouldn't be a bad idea to do add overloads for 
> copyFrom that take an index and offset into account for when the 
> source is a MemorySegment.
>
>
> On 3/31/21 7:41 PM, leerho wrote:
>> Folks,
>>
>> I am in the process of refactoring our code to use FMA (from JDK16) 
>> in our
>> application.  But what I find missing is the ability to do efficient
>> getting and putting of arrays with MemorySegments.
>>
>> What I need to do often is to place part of an existing array into a
>> segment at a specific offset and the reverse; getting an array of 
>> elements
>> from a segment at a specific offset and placing it into an existing 
>> array
>> at a specific offset.  I have looked closely at MemoryAccess and the 
>> latest
>> ByteBuffer, but I have not found anything quite as flexible as the
>> following.
>>
>> What I have ended up doing is creating an entire class of array methods
>> like the following:
>>
>> public class MemoryArrays {
>>>    public static void putIntArray(int[] srcArr, long srcIndex, long
>>> numInts,
>>>        MemorySegment dstSeg, long dstOffsetBytes) {
>>>      MemorySegment srcSeg = MemorySegment.ofArray(srcArr);
>>>      MemorySegment srcSegSlice = srcSeg.asSlice(srcIndex << 2, 
>>> numInts <<
>>> 2);
>>>      MemorySegment dstSegSlice = dstSeg.asSlice(dstOffsetBytes, 
>>> numInts <<
>>> 2);
>>>      dstSegSlice.copyFrom(srcSegSlice);
>>>    }
>>>
>>>    /* ...Same as above for all primitive types... */
>>>
>>>    public static void getIntArray(MemorySegment srcSeg, long
>>> srcOffsetBytes,
>>>        int[] dstArr, long dstIndex, long numInts) {
>>>      MemorySegment srcSegSlice = srcSeg.asSlice(srcOffsetBytes, 
>>> numInts <<
>>> 2);
>>>      MemorySegment dstSeg = MemorySegment.ofArray(dstArr);
>>>      MemorySegment dstSegSlice = dstSeg.asSlice(dstIndex << 2, 
>>> numInts <<
>>> 2);
>>>      dstSegSlice.copyFrom(srcSegSlice);
>>>    }
>>>
>>>    /* ...Same as above for all primitive types... */
>>> }
>>>
>> I would think that if these methods were built-in to FMA either as a
>> separate class or included in MemoryAccess, it would be so much more
>> efficient.  All of these separate
>> calls to MemorySegment could be eliminated and the entire method inlined
>> with a few lines of C++ code.
>>
>> If Panama is interested I would be happy to contribute such a class.
>>
>> Lee.


More information about the panama-dev mailing list