--
You received this message because you are subscribed to the Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-symp...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-sympathy+unsub...@googlegroups.com.
I was looking for an elegant solution for exactly this problem some time ago and didn't find it, before putting that work on hold.
Without coordination between the threads, how do you know that the prefetcher thread is ahead of the main thread? If you consider that the CAS in the prefetcher thread may fail due to concurrent write in the main thread, it means that the page fault will happen in the main thread.
I suspect that JNI call to madvice with something like MADV_WILLNEED | MADV_SEQUENTIAL (and no prefetcher threads) is the most practical solution, but I didn't test this theory.
On Wed, 11 Jul 2018 at 05:30, Ruslan Cheremin <cher...@gmail.com> wrote:
--HelloI have question about working with memory mapped buffers and associated page faults.Scenario: I have main thread, which is writing some data to memory mapped ByteBuffer. The thread is supposed to be kind of soft realtime, thus I don't want it to step onto page faults.So obvious idea is to start another thread, prefetcher, with responsibility to periodically touch buffer 1-2 pages ahead of current writing position, and trigger page faults before main thread step onto them.The question is: how to trigger memory page loading, but without intervening main thread writes?Afaik, read value from yet-not-loaded page is not guaranteed to trigger page mapping (virtual memory managers are tricky beasts, and could fake reads from unmapped pages without mapping them).Write to a page will trigger page loading and mapping, but such a write could overwrite data written from main thread (I.e. in case of unlucky timings main thread could outperform prefetcher thread and already write something in this position.And I'd prefer to avoid introducing heavy coordination between main thread and prefetcher since it greatly complicates both of them)Is there any way to force page loading/mapping without using JNI?Personally, best idea I come to so far is to use CAS(futureBufferPosition, 0, 0) [with help of Unsafe].I tend to think it could work because:1. any plain write actually executed concurrently with CAS will make CAS fail, and no data corruption will happen2. any plain write actually executed _after_ CAS will overwrite value -- it is OK, no problem, I don't care about value written by CAS, only about write op itself3. CAS itself changes nothing in memory (writes 0 instead of 0), but afaik it could not be optimized out by hardware nor by JIT because of additional memory effects -- thus write _will_ be executed and will trigger page-fault.Does it seem reasonable?----Ruslan
You received this message because you are subscribed to the Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-sympathy+unsub...@googlegroups.com.
I suppose that's why reusing already mapped pages in order to avoid major page faults is the way to go, according to both OS configuration and page cache limitations.AFAIK memory mapped heavy based solutions involve the uses of B tree-like free pools to allow reusing already mapped pages/chunks with some madvice magic (as Roman suggested) to help the OS eg lmdb.
The only Java solution I'm aware (with Roman as well, I suppose :P) that uses efficiently a mapped solution for and endless log is chronicle-queue from Peter L.: some time ago I have taken a look and it was usinga pretoucher (https://github.com/OpenHFT/Chronicle-Queue/blob/master/src/main/java/net/openhft/chronicle/queue/impl/single/Pretoucher.java), but I don't know if it was used for this same purpose.
If your requirements are really important, use aio + O_DIRECT. You then know exactly when your memory has the data you want. You don't even need the extra thread.
It's more work for sure, but you are in complete control, instead
of playing whack-a-mole with the JVM.
--
You received this message because you are subscribed to the Google Groups "mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mechanical-symp...@googlegroups.com.
any access to that buffer, even when done in a background thread, may potentially cause stop-the-world like pause, if a page fault concurs with a safepoint request.
What about allocating a regular direct ByteBuffer and flushing it to disk manually using FileChannel API? This approach will retain nearly the same level of simplicity and performance while being a pure Java solution - no JNI or Unsafe required.
any access to that buffer, even when done in a background thread, may potentially cause stop-the-world like pause, if a page fault concurs with a safepoint request.But if it is madvice JNI call -- safepoint issue shouldn't happen? Seems like private MappedByteBuffer.load0(start, length) is mapped exactly to madvice(WILL_NEED), so one don't ever need to white it's own JNI wrapper...
I think what you want is something like the mincore system call on Linux so your thread can write directly if the page is mapped but offload the work to another thread if it is not mapped. I don't have any experience with the system call though.
--
You received this message because you are subscribed to a topic in the Google Groups "mechanical-sympathy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/mechanical-sympathy/yL4Yaedgqg4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to mechanical-symp...@googlegroups.com.
I feel like this is just a bug in the JDK that should be patched.
Couldn't this all be solved by replacing UNSAFE.copyMemory with a call to a different method that isn't a HotSpot intrinsic?Interestingly I don't believe that copySwapMemory is an intrinsic so an ugly kludge might be to use a nonnative byte order deliberately.