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