Improve the call size estimate#15402
Conversation
|
|
src/core/lib/surface/call.h
Outdated
| /* Get the estimated memory size for a call besides the call stack. Combined | ||
| * with the size of the call stack, it helps estimate the arena size for the | ||
| * first call. */ | ||
| size_t grpc_call_get_call_size_estimate_besides_call_stack(); |
There was a problem hiding this comment.
Since this is only helping the estimate for the first call, I think we should add _initial_ in the name.
There was a problem hiding this comment.
I'd suggest just calling this something like grpc_call_get_initial_size_estimate(). We can document the fact that it does not include the call stack.
|
markdroth
left a comment
There was a problem hiding this comment.
I thought that the balancer folks were concerned about per-channel overhead, not per-call overhead -- in other words, the amount of overhead for a channel that is connected but does not have any calls started. This PR addresses per-call overhead, not per-channel overhead. Was I misunderstanding their concern, or is this PR addressing something else?
To be clear, I think you're right that there is a problem here, and this PR (with some concerns addressed) does seem like a reasonable approach. But I think we should also be looking at the per-channel overhead to see if there's something we can reduce there.
Please let me know if you have any questions about any of this.
src/core/lib/surface/call.cc
Outdated
| #define MAX_SEND_EXTRA_METADATA_COUNT 3 | ||
|
|
||
| // These estimates are used to create arena for the first call. | ||
| #define ESTIMATED_BATCH_CONTROL_COUNT 5 |
There was a problem hiding this comment.
Where does this number come from? Do we have any data on the average number of batches per call? If the goal here is to ensure that we always have enough space for all batches, then shouldn't we just use MAX_CONCURRENT_BATCHES instead?
More generally, I am concerned that we may be optimizing for the wrong case here. While this change may benefit the specific use case of a service that has one streaming call per channel, unary RPCs are far more common than streaming, and unary RPCs typically have only 1-2 batches. Will the hysteresis code ensure that we don't allocate more memory than we need after a few RPCs in the unary case?
There was a problem hiding this comment.
Oh, I thought we allocate a new batch_control object for each batch. We actually re-use it. Then we should definitely use MAX_CONCURRENT_BATCHES here.
Yes, the estimated arena size will be updated by previous calls. So subsequent calls will have more accurate size estimated. Unless each channel only has one unary call, we shouldn't be wasting a lot. If there is only one unary call per channel, we are wasting 368B * 4 though.
src/core/lib/surface/call.cc
Outdated
|
|
||
| // These estimates are used to create arena for the first call. | ||
| #define ESTIMATED_BATCH_CONTROL_COUNT 5 | ||
| #define ESTIMATED_MDELEM_COUNT 10 |
There was a problem hiding this comment.
Similar question here: Where does this number come from? Do we have any data on the average number of metadata elements we need to allocate per call?
There was a problem hiding this comment.
From the log, I see 11 mdelem allocated. I learned that the number of metadata (without any user-defined ones) is stable, so I think a rough estimate by this sample is fine.
It might be safer to use a slightly larger number like 16, especially when each mdelem is just 32B.
src/core/lib/surface/call.h
Outdated
| /* Get the estimated memory size for a call besides the call stack. Combined | ||
| * with the size of the call stack, it helps estimate the arena size for the | ||
| * first call. */ | ||
| size_t grpc_call_get_call_size_estimate_besides_call_stack(); |
There was a problem hiding this comment.
I'd suggest just calling this something like grpc_call_get_initial_size_estimate(). We can document the fact that it does not include the call stack.
|
@markdroth From today's meeting, I believe the use scenario of the LB team is one channel plus one call. This is also how they conduct the load tests. |
|
|
|
sanity, you may need clang-format |
|
|
|
|
|
|
1 similar comment
|
71b4ae3 to
25c57a3
Compare
|
|
|
|
|
|
When the first call creates its arena, it shouldn't just estimate the necessary size using the call stack. It should at least include the
grpc_calland some other necessary stuff for a complete call. Otherwise, the arena will be too small for the first allocation for both thegrpc_calland the call stack. And the initial zone of the arena will be wasted and the second zone will grow to twice the size ofgrpc_calland the call stack.This means a lot for the channels that only have one call per channel.
The test of the internal balancer shows that this PR can reduce the memory usage per channel (one bidi steaming call per channel) from ~100KB to ~75KB.