RFR: 8244936: Reduce JNI overhead of accessing FileDescriptor

Peter Levart peter.levart at gmail.com
Mon May 18 08:48:49 UTC 2020


Hi Claes,


One step further would be to eliminate access to 
FileDescriptor.fd/handle from native hot paths altogether and pass the 
fd/handle to native methods from java:


http://cr.openjdk.java.net/~plevart/jdk-dev/8244936_dont_access_FileDescriptor/webrev.01/


This has similar incremental effect on the RandomAccessRead.test micro 
as your patch had:


before:
Benchmark                    (buffer)  (fileSize)   Mode  Cnt Score    
Error   Units
RandomAccessRead.test            8192     1000000  thrpt    5 809.538 ? 
11.658  ops/ms


after:
Benchmark                    (buffer)  (fileSize)   Mode  Cnt Score    
Error   Units
RandomAccessRead.test            8192     1000000  thrpt    5 861.619 ? 
12.307  ops/ms


All jdk_io tests pass on Linux but I don't have a Windows machine at 
hand. So WDYT?


Regards, Peter


On 5/13/20 5:44 PM, Claes Redestad wrote:
> Hi,
>
> compilers can't see though and optimize away the repeated GetObjectField
> calls in places such as in the io_util_md.h GET_FD macro:
>
> #define GET_FD(this, fid) \
>     (*env)->GetObjectField(env, (this), (fid)) == NULL ? \
>         -1 : (*env)->GetIntField(env, (*env)->GetObjectField(env, 
> (this), (fid)), IO_fd_fdID)
>
> This can be avoided if we turn the macros into functions which call
> GetObjectField only once:
>
> FD getFD(JNIEnv *env, jobject this, jfieldID fid) {
>   jobject fd = (*env)->GetObjectField(env, this, fid);
>   if (fd == NULL) {
>     return -1;
>   }
>   return (*env)->GetIntField(env, fd, IO_fd_fdID);
> }
>
> The similarly affected SET_FD is only used in one place, so I removed
> that macro and applied the equivalent optimization at the call-site.
>
> Webrev: http://cr.openjdk.java.net/~redestad/8244936/open.00/
> Bug:    https://bugs.openjdk.java.net/browse/JDK-8244936
>
> This shows an improvement on the existing RandomAccessRead.test micro:
>
> Before:
> Benchmark                (fileSize)  Mode  Cnt  Score   Error Units
> RandomAccessRead.test       1000000  avgt   25  0.832 ± 0.001 us/op
>
> After:
> Benchmark                (fileSize)  Mode  Cnt  Score   Error Units
> RandomAccessRead.test       1000000  avgt   25  0.771 ± 0.005 us/op
>
> ~60ns/op overhead reduction - or ~30ns per native call (the micro calls
> RAF::seek followed by RAF::read).
>
> Since it's an improvement to the constant call overhead, relative gain
> diminishes for larger operations, e.g., reading a 512b buffer sees only
> ~2% improvement, while already on a 8kb read the improvement is more or
> less the noise. I added a read-into-buffer variant of the micro that
> demonstrates.
>
> Still, constant overhead is constant overhead, and operations that only
> read a few bytes is common enough, for example when opening zip files,
> so there's a fair chance for a positive effect in various places. As a
> bonus this refactoring shrinks libjava by a few Kb.
>
> Testing: tier1-2
>
> Thanks!
>
> /Claes


More information about the core-libs-dev mailing list