Memory Segment efficient array handling

Ty Young youngty1997 at gmail.com
Thu Apr 1 04:58:07 UTC 2021


It's kind of a dirty little secret, but FMA just uses Unsafe under the hood:


https://github.com/openjdk/panama-foreign/blob/5a3a9fe4a9f320515f2bef9b22ce0a004f99b260/src/jdk.incubator.foreign/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java#L134


https://github.com/openjdk/panama-foreign/blob/5a3a9fe4a9f320515f2bef9b22ce0a004f99b260/src/java.base/share/classes/jdk/internal/misc/X-ScopedMemoryAccess.java.template#L128


(side note: someone forgot @override on copyFrom in 
AbstractMemorySegmentImpl)


On the issue of alignment, while slicing is awful in regards to on-heap 
allocations, if a MemorySegment represents a distinct type(number, 
pointer, array, struct, union, etc) I think it's OK to do it*. The 
amount of arguments that you have to pass to use that static method and 
its complexity is kind of egregious as-is the amount of overloads for 
everything in MemoryAccess.


*except arrays and array-like struct where you can just use VarHandle 
offsets.


On 3/31/21 10:26 PM, leerho wrote:
> Ty,
> Your idea (with a few corrections) implemented in Java might look like 
> this:
>
>     *public* *static* *void* putIntArray(*int*[] srcArr, *int*
>     srcIndex, *int* numInts,
>
>     MemorySegment dstSeg, *long* dstOffsetBytes) {
>
>     *for* (*int* i = 0; i < numInts; i++) {
>
>     MemoryAccess./setIntAtOffset/(dstSeg, dstOffsetBytes + 4 * i,
>     srcArr[srcIndex + i]);
>
>     }
>
>     }
>
> I have to use "setIntAtOffset" because I can't assume that the 
> integers in the segment are integer aligned.
>
> Thanks again!
> Lee.
>
> On Wed, Mar 31, 2021 at 8:05 PM leerho <leerho at gmail.com 
> <mailto:leerho at gmail.com>> wrote:
>
>     Ty,
>     Thanks, that is an excellent suggestion.  It is my hope, however,
>     to get methods with similar method signatures implemented
>     somewhere in FMA.  If the work was done on the C++ side it should
>     be even more efficient than trying to do the loop in java. 
>     Especially if the data to be put or extracted is very large, the
>     copy loop should be done as a low-level bulk copy.
>
>     Lee.
>
>
>
>
>     On Wed, Mar 31, 2021 at 7:08 PM Ty Young <youngty1997 at gmail.com
>     <mailto:youngty1997 at gmail.com>> 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.
>
>
>         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