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