[go/mysql] use tiered pool for buffers to avoid false hits#4183
[go/mysql] use tiered pool for buffers to avoid false hits#4183sougou merged 1 commit intovitessio:masterfrom LK4D4:tiered_pool
Conversation
|
Let's use a human-readable simplification: This will yield the following buckets: 1, 2, 4, 8, 16. Now, if we perform log operations, with multiplier as base(2), it will yield the index of the pool. Let's say requested length was: 5. Log(5) = 2.3, which rounds up to 3. This approach will allow us to have a larger number of pools. We should have pools of size up to 16M. For minSize other than 1, we have to first divide by minSize before taking the log. |
|
As for returning the last index, the idea is to put everything above the max length into that bucket and take a gamble. The next one that pulls from the pool will have to check the length. But I think that's not worth it. So, it's better to just allocate from heap. |
|
@sougou is it okay to fix multiplier as 2? Because there is no arbitrary base logarithm in go it seems. |
|
Yeah. I was surprised about that. But 2 is a good multiplier to hard-code. |
go/bucketpool/bucketpool_test.go
Outdated
go/bucketpool/bucketpool.go
Outdated
There was a problem hiding this comment.
Now when we get smaller than we want buffer from pool, we just put it back and allocate a new one. This might be quite inefficient. So, instead use multiple pools which always return buffers >= request size. Signed-off-by: Alexander Morozov <lk4d4math@gmail.com>
|
@sougou @danieltahara PTAL |
danieltahara
left a comment
There was a problem hiding this comment.
Looks good! One note about deprecating the huge allocation path (length >= MaxPacketSize), since it's handled gracefully here.
| if length < MaxPacketSize { | ||
| c.currentEphemeralPolicy = ephemeralReadSingleBuffer | ||
| c.currentEphemeralReadBuffer = getBuf(length) | ||
| c.currentEphemeralReadBuffer = bufPool.Get(length) |
There was a problem hiding this comment.
we should be able to remove the huge allocation path as well, right?
There was a problem hiding this comment.
There is one path with direct which makes something different IIRC. I will take a closer look.
There was a problem hiding this comment.
yeah i think we can defer to c.buffer diff
|
@sougou jumping back over here -- since this doesn't get rid of c.buffer yet, is this good to go? |
Now when we get smaller than we want buffer from pool, we just put it
back and allocate a new one. This might be quite inefficient.
So, instead use multiple pools which always return buffers >= request
size.
Benchmark results:
This is new package and internal to vitess. So, we can make interface less flexible maybe. Like allow only powers of two and say that multiplier is always 2.