Skip to content
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

Implement faster pointer rebasing. #1696

Merged
merged 1 commit into from Nov 30, 2020
Merged

Conversation

Lukasa
Copy link
Contributor

@Lukasa Lukasa commented Nov 27, 2020

Motivation:

I recently discovered that UnsafeRawBufferPointer.init(rebasing:) is
surprisingly expensive, with 7 traps and 11 branches. A simple
replacement can make it a lot cheaper, down to two traps and four
branches. This ends up having pretty drastic effects on
ByteBuffer-heavy NIO code, which often outlines the call to that
initializer and loses the ability to make a bunch of site-local
optimisations.

While this has been potentially fixed upstream with
apple/swift#34879, there is no good reason to
wait until Swift 5.4 for this improvement.

Due to the niche use-case, I didn't bother doing this for every
rebasing in the program. In particular, there is at least one
UnsafeBufferPointer(rebasing:) that I didn't do this with, and there are
uses in both NIOTLS and NIOHTTP1 that I didn't change. While we can fix
those if we really need to, it would be nice to avoid this helper
proliferating too far through our codebase.

Modifications:

  • Replaced the use of URBP.init(rebasing:) with a custom hand-rolled
    version that avoids Slice.count.

Result:

Cheaper code. One NIOHTTP2 benchmark sees a 2.9% speedup from this
change alone.

Motivation:

I recently discovered that UnsafeRawBufferPointer.init(rebasing:) is
surprisingly expensive, with 7 traps and 11 branches. A simple
replacement can make it a lot cheaper, down to two traps and four
branches. This ends up having pretty drastic effects on
ByteBuffer-heavy NIO code, which often outlines the call to that
initializer and loses the ability to make a bunch of site-local
optimisations.

While this has been potentially fixed upstream with
apple/swift#34879, there is no good reason to
wait until Swift 5.4 for this improvement.

Due to the niche use-case, I didn't bother doing this for _every_
rebasing in the program. In particular, there is at least one
UnsafeBufferPointer(rebasing:) that I didn't do this with, and there are
uses in both NIOTLS and NIOHTTP1 that I didn't change. While we can fix
those if we really need to, it would be nice to avoid this helper
proliferating too far through our codebase.

Modifications:

- Replaced the use of URBP.init(rebasing:) with a custom hand-rolled
  version that avoids Slice.count.

Result:

Cheaper code. One NIOHTTP2 benchmark sees a 2.9% speedup from this
change alone.
@Lukasa Lukasa added the patch-version-bump-only For PRs that when merged will only cause a bump of the patch version, ie. 1.0.x -> 1.0.(x+1) label Nov 27, 2020
@glbrntt glbrntt merged commit 4bf379b into apple:main Nov 30, 2020
Lukasa added a commit to Lukasa/swift-nio that referenced this pull request Jan 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
patch-version-bump-only For PRs that when merged will only cause a bump of the patch version, ie. 1.0.x -> 1.0.(x+1)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants