Memory Segment efficient array handling

Ty Young youngty1997 at gmail.com
Thu Apr 1 02:08:33 UTC 2021


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.


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