RFR: 8265175: (fs) Files.copy(Path, Path, CopyOption...) should use sendfile on Linux [v3]
Alan Bateman
alanb at openjdk.java.net
Thu Apr 15 11:12:35 UTC 2021
On Wed, 14 Apr 2021 23:47:57 GMT, Brian Burkhalter <bpb at openjdk.org> wrote:
>> Please consider this request to change the underlying native implementation of `java.nio.file.Files.copy(Path,Path,CopyOption...)` on Linux only to perform zero-copy via `sendfile(2)`. The `sendfile()` system call is already used in `java.nio.channels.FIleChannel.transferTo(long,long,WritableByteChannel)`. It is intentionally _not_ proposed to use `sendfile()` in the native macOS implementation as on macOS the function requires that the destination file descriptor is for a socket.
>>
>> This change showed some performance improvement as measured by JMH.
>>
>> **Before: user-space buffers (read() + write())**
>>
>> Benchmark (size) Mode Cnt Score Error Units
>> FilesCopy.copy 10240 thrpt 5 39167.400 ± 683.887 ops/s
>> FilesCopy.copy 51200 thrpt 5 20782.622 ± 558.031 ops/s
>> FilesCopy.copy 102400 thrpt 5 13260.709 ± 176.673 ops/s
>> FilesCopy.copy 512000 thrpt 5 3171.837 ± 175.803 ops/s
>> FilesCopy.copy 1048568 thrpt 5 1654.253 ± 39.419 ops/s
>> FilesCopy.copy 10485760 thrpt 5 145.328 ± 7.192 ops/s
>> FilesCopy.copy 104857600 thrpt 5 12.440 ± 2.275 ops/s
>> FilesCopy.copy 1073741824 thrpt 5 1.073 ± 0.081 ops/s
>>
>> **After: zero-copy (sendfile())**
>>
>> Benchmark (size) Mode Cnt Score Error Units
>> FilesCopy.copy 10240 thrpt 5 40571.516 ± 548.977 ops/s
>> FilesCopy.copy 51200 thrpt 5 23993.334 ± 506.817 ops/s
>> FilesCopy.copy 102400 thrpt 5 15927.485 ± 309.081 ops/s
>> FilesCopy.copy 512000 thrpt 5 4207.129 ± 95.454 ops/s
>> FilesCopy.copy 1048568 thrpt 5 2147.046 ± 33.446 ops/s
>> FilesCopy.copy 10485760 thrpt 5 148.798 ± 1.329 ops/s
>> FilesCopy.copy 104857600 thrpt 5 14.541 ± 0.675 ops/s
>> FilesCopy.copy 1073741824 thrpt 5 1.270 ± 0.029 ops/s
>
> Brian Burkhalter has updated the pull request incrementally with three additional commits since the last revision:
>
> - Merge
> - 8265175: Delete fstat() calls, read to EOF, change sendfile() to sendfile64(), handle EINTR case
> - 8265175: (fs) Files.copy(Path,Path,CopyOption...) should use sendfile on Linux
src/java.base/unix/native/libnio/fs/UnixCopyFile.c line 79:
> 77: return;
> 78: }
> 79: #endif
This version looks much better but it missing the error checking. If bytes_sent is -1 then we should throw UnixException with the errno like the existing code.
What would you think about setting count to 1MB or 4MB so that there is at least some chance for cancellation when the file is huge.
Given that the new implementation will call sendfile64 until EOF then there is no reason to fall through to the old implementation, the old implementation goes into the #else ...
-------------
PR: https://git.openjdk.java.net/jdk/pull/3476
More information about the nio-dev
mailing list