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

Pool buffers per handler and client #192

Merged
merged 10 commits into from
Apr 9, 2022
Merged

Pool buffers per handler and client #192

merged 10 commits into from
Apr 9, 2022

Conversation

bufdev
Copy link
Member

@bufdev bufdev commented Apr 7, 2022

This doesn't actually work yet, I messed up something with lpm where it's causing an infinite loop (likely with my slicing into raw.Bytes()), but just demonstrating the idea: Instead of a global sync.Pool, we could just thread it down on a per-Client/Handler basis.

@bufdev bufdev requested a review from akshayjshah April 7, 2022 20:35
@bufdev
Copy link
Member Author

bufdev commented Apr 8, 2022

@akshayjshah to take this over

@akshayjshah akshayjshah changed the title WIP: Add bufferPool Pool buffers per handler and client Apr 8, 2022
@akshayjshah
Copy link
Member

Fixed this up - tests and lint are passing now, and I found an unrelated bug along the way. I'll pull the unrelated fix out into a separate PR (it's unfortunately difficult to unit test), get this rebased, and post the performance diff later tonight.

The bulk of the actual logic changes are in bufbuild@fccf9fd (marshaling) and bufbuild@f396e2c (unmarshaling).

bufdev and others added 6 commits April 8, 2022 20:15
@akshayjshah akshayjshah force-pushed the per-instance-buffer-pools branch from 3413e46 to 09a7397 Compare April 9, 2022 03:15
When we want to use a pooled buffer as a byte slice, we have to first
call `Grow` (to ensure adequate capacity) and then reslice to set
`len(raw)` to `cap(raw)`.
@akshayjshah akshayjshah force-pushed the per-instance-buffer-pools branch from 09a7397 to 8016997 Compare April 9, 2022 03:24
Currently, the benchmark is a bit unrealistic - the wire size of the
payload is single-digit bytes. This makes the payload slightly bigger,
though it still compresses unrealistically well.
@akshayjshah
Copy link
Member

Changed the benchmarks to use a slightly more realistic payload (a 2 MiB string, though it compresses unreasonably well). I ran the benchmarks on main with the benchmark changes cherry-picked in, then on this PR. Comparison:

name              old time/op    new time/op    delta
Connect/unary-10    1.82ms ± 0%    1.44ms ± 0%  -21.18%

name              old alloc/op   new alloc/op   delta
Connect/unary-10    25.1MB ± 0%    14.7MB ± 0%  -41.41%

name              old allocs/op  new allocs/op  delta
Connect/unary-10       360 ± 0%       288 ± 0%  -20.00%

A 20% speed improvement and a 40% reduction in allocated memory seems worthwhile! If we want to simplify the implementation a bit, we can stop pooling rawBuffer in marshalLPM - the way we need to Grow and reslice it is a bit more complicated than the other places we're using buffer pools.

rawBuffer := u.bufferPool.Get()
defer u.bufferPool.Put(rawBuffer)
rawBuffer.Grow(size)
raw := rawBuffer.Bytes()[0:size]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just making sure - are there any concerns with this not being memset 0'ed?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think so - we're being very careful not to continue on if we don't read size bytes off the network. No harm zeroing it, though!

@bufdev bufdev merged commit b574f42 into main Apr 9, 2022
@bufdev bufdev deleted the per-instance-buffer-pools branch April 9, 2022 15:08
@akshayjshah
Copy link
Member

akshayjshah commented Apr 9, 2022 via email

akshayjshah pushed a commit that referenced this pull request Jul 26, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants