Skip to content

8265891: (ch) InputStream returned by Channels.newInputStream should override transferTo #4263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 23 commits into from

Conversation

mkarg
Copy link
Contributor

@mkarg mkarg commented May 30, 2021

This PR-draft is work in progress and an invitation to discuss a possible solution for issue JDK-8265891. It is not yet intended for a final review.

As proposed in JDK-8265891, this PR provides an implementation for Channels.newInputStream().transferTo() which provide superior performance compared to the current implementation. The changes are:

  • Prevents transfers through the JVM heap as much as possibly by offloading to deeper levels via NIO, hence allowing the operating system to optimize the transfer.
  • Using more JRE heap in the fallback case when no NIO is possible (still only KiBs, hence mostl ynegligible even on SBCs) to better perform on modern hardware / fast I/O devides.

Using JMH I have benchmarked both, the original implementation and this implementation, and (depending on the used hardware and use case) performance change was approx. doubled performance. So this PoC proofs that it makes sense to finalize this work and turn it into an actual OpenJDK contribution.

I encourage everybody to discuss this draft:

  • Are there valid arguments for not doing this change?
  • Is there a better way to improve performance of Channels.newInputStream().transferTo()?
  • How to go on from here: What is missing to get this ready for an actual review?

Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed

Issue

  • JDK-8265891: (ch) InputStream returned by Channels.newInputStream should override transferTo

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.java.net/jdk pull/4263/head:pull/4263
$ git checkout pull/4263

Update a local copy of the PR:
$ git checkout pull/4263
$ git pull https://git.openjdk.java.net/jdk pull/4263/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 4263

View PR using the GUI difftool:
$ git pr show -t 4263

Using diff file

Download this PR as a diff file:
https://git.openjdk.java.net/jdk/pull/4263.diff

mkarg added 2 commits May 30, 2021 17:46
Preventing transfer through the JVM heap by using NIO and potentially
performing intra-OS transport to improve performance where possible.

Signed-off-by: Markus Karg <markus@headcrashing.eu>
These days I/O devides, particularly SSDs, are much faster than in the
days this original code was written. Due to that, the transfer time is
less I/O bound. Performance can be increased significantly by spending
16x 8 KiB instead of the original 1x 8 KiB heap memory (approx. doubles
performance, clearly depending on the used hardware).

Signed-off-by: Markus Karg <markus@headcrashing.eu>
@bridgekeeper bridgekeeper bot added the oca Needs verification of OCA signatory status label May 30, 2021
@bridgekeeper
Copy link

bridgekeeper bot commented May 30, 2021

Hi @mkarg, welcome to this OpenJDK project and thanks for contributing!

We do not recognize you as Contributor and need to ensure you have signed the Oracle Contributor Agreement (OCA). If you have not signed the OCA, please follow the instructions. Please fill in your GitHub username in the "Username" field of the application. Once you have signed the OCA, please let us know by writing /signed in a comment in this pull request.

If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please use "Add GitHub user mkarg" as summary for the issue.

If you are contributing this work on behalf of your employer and your employer has signed the OCA, please let us know by writing /covered in a comment in this pull request.

@openjdk
Copy link

openjdk bot commented May 30, 2021

@mkarg The following labels will be automatically applied to this pull request:

  • core-libs
  • nio

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added nio nio-dev@openjdk.org core-libs core-libs-dev@openjdk.org labels May 30, 2021
@mkarg
Copy link
Contributor Author

mkarg commented May 30, 2021

/signed

@bridgekeeper bridgekeeper bot added the oca-verify Needs verification of OCA signatory status label May 30, 2021
@bridgekeeper
Copy link

bridgekeeper bot commented May 30, 2021

Thank you! Please allow for up to two weeks to process your OCA, although it is usually done within one to two business days. Also, please note that pull requests that are pending an OCA check will not usually be evaluated, so your patience is appreciated!

@bridgekeeper bridgekeeper bot removed oca Needs verification of OCA signatory status oca-verify Needs verification of OCA signatory status labels Jun 1, 2021
mkarg added 2 commits June 4, 2021 19:03
Signed-off-by: Markus Karg <markus@headcrashing.eu>
Signed-off-by: Markus Karg <markus@headcrashing.eu>
Signed-off-by: Markus Karg <markus@headcrashing.eu>
@mkarg
Copy link
Contributor Author

mkarg commented Jun 5, 2021

@AlanBateman I'm done with the changes you requested and kindly like to ask where to go from here.

@AlanBateman
Copy link
Contributor

AlanBateman commented Jun 8, 2021

@AlanBateman I'm done with the changes you requested and kindly like to ask where to go from here.

Moving ChannelOutputStream to sun.nio.ch looks right. The implementation of transferTo will need a few rounds of cleanup, it's a look very messy right now. You are over using var and is impossible for the reader to know what the types are. Pattern matching for instanceof can be used to avoid the casts.

@mkarg
Copy link
Contributor Author

mkarg commented Jun 8, 2021

Great ideas, will do as you say, stay tuned! Didn't know that using var is a no-go, sorry for that. Pattern matching is definitively a great idea!

Signed-off-by: Markus Karg <markus@headcrashing.eu>
@mkarg
Copy link
Contributor Author

mkarg commented Jun 8, 2021

Replaced var by actual type in b3c62b0.

Signed-off-by: Markus Karg <markus@headcrashing.eu>
@mkarg
Copy link
Contributor Author

mkarg commented Jun 8, 2021

Replaced casting by pattern matching for instanceof in ac62cdb.

@mkarg
Copy link
Contributor Author

mkarg commented Jun 8, 2021

@AlanBateman Pushed the requested changes. More change requests? :-)

Signed-off-by: Markus Karg <markus@headcrashing.eu>
Signed-off-by: Markus Karg <markus@headcrashing.eu>
@mkarg
Copy link
Contributor Author

mkarg commented Aug 15, 2021

Does it make any real sense to answer your recent questions, provide the proofs, tests and benchmark results (I actually would love to if it makes sense) or will the outcome be that I must drop everything besides file channels anyways (In that case it is in vain)? As my time is just as precious as yours I really need to know that before I spend more weeks into code paths that you possibly decided to never accept ever. Don't get me wrong, if you see a chance to keep the code once I provided the answers I will do that, but if you do not see that chance, please frankly and unambiguously tell me now. Thanks.

I think the best course of action is to reduce the scope of this PR to the file channel cases. There is no reason why future PRs can't build on this and add implementations for other channel types.

Agreed, I will split this PR into several PRs, so we can start with the low-hanging fruits first and later dive into the more complex cases.

@mkarg
Copy link
Contributor Author

mkarg commented Aug 19, 2021

I think the best course of action is to reduce the scope of this PR to the file channel cases. There is no reason why future PRs can't build on this and add implementations for other channel types.

I have split up this PR so that only the lowest hanging fruit is covered and kindly request review: #5179.

@mkarg mkarg marked this pull request as draft August 31, 2021 06:30
@openjdk openjdk bot removed the rfr Pull request is ready for review label Aug 31, 2021
@bridgekeeper
Copy link

bridgekeeper bot commented Sep 26, 2021

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Oct 10, 2021

Work on this draft will be continued as soon as depenency PRs are resolved. Please keep this issue open.

@bridgekeeper
Copy link

bridgekeeper bot commented Nov 7, 2021

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Nov 7, 2021

Please keep this PR open. More commits will follow on the next weeks.

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 5, 2021

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Dec 6, 2021

Please keep this PR open. More commits will follow on the next weeks.

@bourgesl
Copy link
Contributor

bourgesl commented Dec 6, 2021

Looks promising, keep moving, @mkarg !

@mkarg
Copy link
Contributor Author

mkarg commented Dec 12, 2021

Looks promising, keep moving, @mkarg !

Thanks a lot, Laurent! I really appreciate! In fact, most of the work is going on in spin-off PRs, and some of it already is merged, as I explained on Twitter and Youtube. :-)

@bridgekeeper
Copy link

bridgekeeper bot commented Jan 14, 2022

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Jan 15, 2022

Please keep this PR open as I am working on several sub-issues currently.

@bridgekeeper
Copy link

bridgekeeper bot commented Feb 12, 2022

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Feb 13, 2022

Please keep this PR open. I am still working on it.

@bridgekeeper
Copy link

bridgekeeper bot commented Mar 13, 2022

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Mar 13, 2022

Please keep this PR open; I will continune work on it soon.

@bridgekeeper
Copy link

bridgekeeper bot commented May 8, 2022

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented May 13, 2022

Please keep this PR open; I will continune work on it soon.

@bridgekeeper
Copy link

bridgekeeper bot commented Jul 8, 2022

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@mkarg
Copy link
Contributor Author

mkarg commented Jul 8, 2022

Please keep this PR open; I will continune work on it soon.

@bridgekeeper
Copy link

bridgekeeper bot commented Sep 3, 2022

@mkarg This pull request has been inactive for more than 8 weeks and will be automatically closed if another 8 weeks passes without any activity. To avoid this, simply add a new comment to the pull request. Feel free to ask for assistance if you need help with progressing this pull request towards integration!

@bridgekeeper
Copy link

bridgekeeper bot commented Oct 29, 2022

@mkarg This pull request has been inactive for more than 16 weeks and will now be automatically closed. If you would like to continue working on this pull request in the future, feel free to reopen it! This can be done using the /open pull request command.

@bridgekeeper bridgekeeper bot closed this Oct 29, 2022
@laeubi
Copy link

laeubi commented Oct 30, 2022

Hi @laeubi, thanks for making a comment in an OpenJDK project!

All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user laeubi for the summary.

If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.

Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.

@mkarg
Copy link
Contributor Author

mkarg commented Oct 31, 2022

@laeubi The performance was optimized by several PRs (works well for file based streams now), but there are still cases that could (possibly should) get optimized. These cases are still on my agenda. But before I continue with those cases, I focus on enabling that optimization (BufferedInputStream prevents the benefit in most cases, but #10525 will fix that, so I can step on soon).

@laeubi
Copy link

laeubi commented Oct 31, 2022

Hi @laeubi, thanks for making a comment in an OpenJDK project!

All comments and discussions in the OpenJDK Community must be made available under the OpenJDK Terms of Use. If you already are an OpenJDK Author, Committer or Reviewer, please click here to open a new issue so that we can record that fact. Please Use "Add GitHub user laeubi for the summary.

If you are not an OpenJDK Author, Committer or Reviewer, simply check the box below to accept the OpenJDK Terms of Use for your comments.

Your comment will be automatically restored once you have accepted the OpenJDK Terms of Use.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core-libs core-libs-dev@openjdk.org nio nio-dev@openjdk.org
Development

Successfully merging this pull request may close these issues.

6 participants