Hi Paul,

We would like to have an an API for Intel's 3D XPoint memory sooner than the 
JDK 10 timeframe and proposed this API because it seems simple enough to 
consider for JDK 9.  As you suggest, we will participate in the Panama 
discussions  in this area.  Any additional guidance you have would be 
appreciated.

Just to clarify, it is incidental that the proposed Memory interface has only 
one method.  We see the value of the interface as nominative; a new type that 
can be passed around to abstract various sources of ByteBuffer memory.

Regarding construction and allocation, our current Memory implementation 
allocates ByteBuffers by calling the NewDirectByteBuffer JNI function with a 
pointer to 3D XPoint memory allocated via a supporting native library.  The 
Linux libraries we have worked with are NVML (https://github.com/pmem/nvml/) 
and memkind (https://github.com/memkind/memkind).  We recently also became 
aware of the NVM-Direct library (https://github.com/oracle/NVM-Direct).  We 
currently don't need our own subclass and return the ByteBuffer returned by the 
JNI call.

Thanks,
Steve

On Apr 6, 2016, at 4:10 AM, Paul Sandoz 
<paul.san...@oracle.com<mailto:paul.san...@oracle.com>> wrote:

Hi Steve,

My feeling is it’s too premature to introduce a general Memory (region) 
allocation interface at this moment. What is currently specified can be 
supported using:

 IntFunction<ByteBuffer>

But i don’t wanna discourage you! this thread has raised some interesting 
points.

Project Panama is gonna take a swing at defining a more general notion of a 
memory region and the Arrays 2.0 work should support indexes greater than 
Integer.MAX_VALUE.

In this respect I think we should hold off doing anything premature for Java 9 
(feature freeze is getting closer), and i encourage you to participate on the 
Panama lists.


—

Here is some context some of which you probably know and some which you might 
not:

- ByteBuffer constructors are deliberately package scoped, as there are some 
intricate dependencies between the implementations and we want control over who 
can implement. Any new form of allocation will require changes here (package 
scoped or otherwise).

- current ByteBuffer implementations are either backed by a byte[] (managed or 
non-direct) or an off-heap allocated (direct) region. At the moment access to 
both those regions go through separate code paths, but they could be unified 
using the Unsafe double addressing mode, which should greatly simplify the 
implementations. I have started making some small steps towards that 
(JDK-8149469 and JDK-8151163). Even these small steps require careful analysis 
to evaluate performance across multiple platforms.

- VarHandles leverages the Unsafe double addressing mode to support enhanced 
atomic access to heap or direct ByteBuffers [1], thus the same code is used in 
both kinds of buffer.


—

I am not sure what plans you have for buffer implementations themselves.

How do you propose to allocate a ByteBuffer instance that covers a region of 3D 
XPoint memory?

Would it be similar to that of direct buffers, e.g. a variation of 
DirectByteBuffer, but with different factory constructor code to allocate the 
memory region within the XPoint memory system and assign the buffer base 
address to the start of that allocated region?

Thanks,
Paul.

[1] 
http://cr.openjdk.java.net/~psandoz/jdk9/varhandles/specdiff/java/lang/invoke/MethodHandles-report.html#method:byteBufferViewVarHandle(java.lang.Class,
 boolean)


On 6 Apr 2016, at 03:49, Dohrmann, Steve 
<steve.dohrm...@intel.com<mailto:steve.dohrm...@intel.com>> wrote:

Re: JDK-8153111<https://bugs.openjdk.java.net/browse/JDK-8153111>


Hi,

Below are responses to some of the points brought up in the discussion as well 
as is a little expansion of the reasoning that went into the proposed API.

One motivation we saw for doing anything beyond a concrete ByteBuffer class was 
application code (e.g. Cassandra) that allocates many off-heap ByteBuffers 
using ByteBuffer#allocateDirect.  We reasoned that if the allocation of 
ByteBuffers could be done using a common memory interface then only the code 
that provisioned instances of the the memory spaces would have to change in 
order to switch or mix memory types.

We did think of overloading the ByteBuffer#allocateDirect method with memory 
space info and avoid an allocation interface.  We ended up with a separate user 
called interface scheme because we imagined that extensions of the memory 
interface would enable new memory functionality that required new methods (e.g. 
memory transactions for persistence).  Without a separate callable interface, 
the static method space in ByteBuffer might have to change again.

For any API In general we saw the need for two things 1) something to represent 
a memory space from which objects are allocated (a Memory instance) and 2) a 
broadly usable familiar "anchor" type as the common data object 
(java.nio.ByteBuffer).

The two points for extension with the current proposal are: 1) Constructors on 
Memory implementation classes -- allow implementors the ability to offer 
features on the memory space itself (e.g. partitioning, size limits) and 2) 
future extensions on the Memory interface -- for example PersistentMemory.

Regarding a more elaborate scheme for memory space creation -- we did consider 
a factory scheme for memory object allocation but could not get comfortable 
with either a) standardized method signatures suitable for various kinds of 
memory or b) the complexity that something like a general-purpose "spec" format 
would add, even if we could come up with it.  Direct construction does expose 
more to the user but it seems sufficient and might be the best given what we 
can say about the future of heterogeneous memory at this point.

Regarding the suggested addition of keyed access to ByteBuffers, we are 
assuming this is only proposed to enable sharing?  We thought it might take a 
while to properly explore the details (i.e. semantics / thread safety / 
predicable performance) of sharing such that it would work well and maybe even 
extend well to things like process-shared and cluster-shared ByteBuffers.  We 
elected to propose nothing for JDK 9 beyond what developers can already do with 
schemes based on e.g. ByteBuffer#duplicate.  We were thinking shared buffers 
could appear later, possibly as an extension of the Memory interface.   The 
keyed access scheme is simple and appealing, however.  One question: how is the 
request method's size parameter to be interpreted?

The suggestion of parameterizing the Memory interface bounded by ByteBuffers 
seems useful as it gives a clean way to support extended ByteBuffers.  Not sure 
if the change of the allocation method name from #allocateByteBuffer to 
#allocate was incidental or not?

Alternates to the "Memory" interface name might be preferred, BufferSupplier is 
certainly reasonable.  We imagined instances that name different memory spaces 
(e.g. OffHeapRAM) for allocation rather that the role played -- thinking the 
role is explicit in the allocation method name (allocateByteBuffer).

Regarding changing the allocation size parameter to a long, this would be very 
nice to have.  We avoided it in order to match the existing ByteBuffer API.  If 
64-bit ByteBuffers are planned, sticking with int sizes might have been the 
wrong call.

We are still coming up to speed on VarHandles (JEP 193), atomics for 
ByteBuffers (JDK-8008240), and ByteBuffer consistency (JDK-6476827).

We hope there is continued interest in this proposal and happy to provide a 
modified patch.

Best regards,
Steve Dohrmann



Reply via email to