[channel] Separate call size estimation out of `grpc_core::Channel` (#35732)

Closes #35732

COPYBARA_INTEGRATE_REVIEW=https://github.com/grpc/grpc/pull/35732 from ctiller:chan 0d7a29fc77
PiperOrigin-RevId: 602865976
pull/35664/head
Craig Tiller 10 months ago committed by Copybara-Service
parent 7b947ec227
commit 59004b4931
  1. 1
      BUILD
  2. 3
      CMakeLists.txt
  3. 2
      Makefile
  4. 2
      Package.swift
  5. 6
      build_autogenerated.yaml
  6. 1
      config.m4
  7. 1
      config.w32
  8. 2
      gRPC-C++.podspec
  9. 3
      gRPC-Core.podspec
  10. 2
      grpc.gemspec
  11. 3
      grpc.gyp
  12. 2
      package.xml
  13. 11
      src/core/BUILD
  14. 22
      src/core/lib/surface/channel.cc
  15. 21
      src/core/lib/surface/channel.h
  16. 41
      src/core/lib/transport/call_size_estimator.cc
  17. 52
      src/core/lib/transport/call_size_estimator.h
  18. 1
      src/python/grpcio/grpc_core_dependencies.py
  19. 2
      tools/doxygen/Doxyfile.c++.internal
  20. 2
      tools/doxygen/Doxyfile.core.internal

@ -1533,6 +1533,7 @@ grpc_cc_library(
"//src/core:bitset",
"//src/core:call_filters",
"//src/core:call_final_info",
"//src/core:call_size_estimator",
"//src/core:call_spine",
"//src/core:cancel_callback",
"//src/core:channel_args",

3
CMakeLists.txt generated

@ -2528,6 +2528,7 @@ add_library(grpc
src/core/lib/transport/bdp_estimator.cc
src/core/lib/transport/call_filters.cc
src/core/lib/transport/call_final_info.cc
src/core/lib/transport/call_size_estimator.cc
src/core/lib/transport/call_spine.cc
src/core/lib/transport/connectivity_state.cc
src/core/lib/transport/error_utils.cc
@ -3244,6 +3245,7 @@ add_library(grpc_unsecure
src/core/lib/transport/bdp_estimator.cc
src/core/lib/transport/call_filters.cc
src/core/lib/transport/call_final_info.cc
src/core/lib/transport/call_size_estimator.cc
src/core/lib/transport/call_spine.cc
src/core/lib/transport/connectivity_state.cc
src/core/lib/transport/error_utils.cc
@ -5332,6 +5334,7 @@ add_library(grpc_authorization_provider
src/core/lib/transport/batch_builder.cc
src/core/lib/transport/call_filters.cc
src/core/lib/transport/call_final_info.cc
src/core/lib/transport/call_size_estimator.cc
src/core/lib/transport/call_spine.cc
src/core/lib/transport/connectivity_state.cc
src/core/lib/transport/error_utils.cc

2
Makefile generated

@ -1710,6 +1710,7 @@ LIBGRPC_SRC = \
src/core/lib/transport/bdp_estimator.cc \
src/core/lib/transport/call_filters.cc \
src/core/lib/transport/call_final_info.cc \
src/core/lib/transport/call_size_estimator.cc \
src/core/lib/transport/call_spine.cc \
src/core/lib/transport/connectivity_state.cc \
src/core/lib/transport/error_utils.cc \
@ -2260,6 +2261,7 @@ LIBGRPC_UNSECURE_SRC = \
src/core/lib/transport/bdp_estimator.cc \
src/core/lib/transport/call_filters.cc \
src/core/lib/transport/call_final_info.cc \
src/core/lib/transport/call_size_estimator.cc \
src/core/lib/transport/call_spine.cc \
src/core/lib/transport/connectivity_state.cc \
src/core/lib/transport/error_utils.cc \

2
Package.swift generated

@ -1903,6 +1903,8 @@ let package = Package(
"src/core/lib/transport/call_filters.h",
"src/core/lib/transport/call_final_info.cc",
"src/core/lib/transport/call_final_info.h",
"src/core/lib/transport/call_size_estimator.cc",
"src/core/lib/transport/call_size_estimator.h",
"src/core/lib/transport/call_spine.cc",
"src/core/lib/transport/call_spine.h",
"src/core/lib/transport/connectivity_state.cc",

@ -1179,6 +1179,7 @@ libs:
- src/core/lib/transport/bdp_estimator.h
- src/core/lib/transport/call_filters.h
- src/core/lib/transport/call_final_info.h
- src/core/lib/transport/call_size_estimator.h
- src/core/lib/transport/call_spine.h
- src/core/lib/transport/connectivity_state.h
- src/core/lib/transport/custom_metadata.h
@ -1983,6 +1984,7 @@ libs:
- src/core/lib/transport/bdp_estimator.cc
- src/core/lib/transport/call_filters.cc
- src/core/lib/transport/call_final_info.cc
- src/core/lib/transport/call_size_estimator.cc
- src/core/lib/transport/call_spine.cc
- src/core/lib/transport/connectivity_state.cc
- src/core/lib/transport/error_utils.cc
@ -2630,6 +2632,7 @@ libs:
- src/core/lib/transport/bdp_estimator.h
- src/core/lib/transport/call_filters.h
- src/core/lib/transport/call_final_info.h
- src/core/lib/transport/call_size_estimator.h
- src/core/lib/transport/call_spine.h
- src/core/lib/transport/connectivity_state.h
- src/core/lib/transport/custom_metadata.h
@ -3050,6 +3053,7 @@ libs:
- src/core/lib/transport/bdp_estimator.cc
- src/core/lib/transport/call_filters.cc
- src/core/lib/transport/call_final_info.cc
- src/core/lib/transport/call_size_estimator.cc
- src/core/lib/transport/call_spine.cc
- src/core/lib/transport/connectivity_state.cc
- src/core/lib/transport/error_utils.cc
@ -4673,6 +4677,7 @@ libs:
- src/core/lib/transport/batch_builder.h
- src/core/lib/transport/call_filters.h
- src/core/lib/transport/call_final_info.h
- src/core/lib/transport/call_size_estimator.h
- src/core/lib/transport/call_spine.h
- src/core/lib/transport/connectivity_state.h
- src/core/lib/transport/custom_metadata.h
@ -4970,6 +4975,7 @@ libs:
- src/core/lib/transport/batch_builder.cc
- src/core/lib/transport/call_filters.cc
- src/core/lib/transport/call_final_info.cc
- src/core/lib/transport/call_size_estimator.cc
- src/core/lib/transport/call_spine.cc
- src/core/lib/transport/connectivity_state.cc
- src/core/lib/transport/error_utils.cc

1
config.m4 generated

@ -838,6 +838,7 @@ if test "$PHP_GRPC" != "no"; then
src/core/lib/transport/bdp_estimator.cc \
src/core/lib/transport/call_filters.cc \
src/core/lib/transport/call_final_info.cc \
src/core/lib/transport/call_size_estimator.cc \
src/core/lib/transport/call_spine.cc \
src/core/lib/transport/connectivity_state.cc \
src/core/lib/transport/error_utils.cc \

1
config.w32 generated

@ -803,6 +803,7 @@ if (PHP_GRPC != "no") {
"src\\core\\lib\\transport\\bdp_estimator.cc " +
"src\\core\\lib\\transport\\call_filters.cc " +
"src\\core\\lib\\transport\\call_final_info.cc " +
"src\\core\\lib\\transport\\call_size_estimator.cc " +
"src\\core\\lib\\transport\\call_spine.cc " +
"src\\core\\lib\\transport\\connectivity_state.cc " +
"src\\core\\lib\\transport\\error_utils.cc " +

2
gRPC-C++.podspec generated

@ -1283,6 +1283,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_size_estimator.h',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',
@ -2538,6 +2539,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_size_estimator.h',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',

3
gRPC-Core.podspec generated

@ -2012,6 +2012,8 @@ Pod::Spec.new do |s|
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.cc',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_size_estimator.cc',
'src/core/lib/transport/call_size_estimator.h',
'src/core/lib/transport/call_spine.cc',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/connectivity_state.cc',
@ -3316,6 +3318,7 @@ Pod::Spec.new do |s|
'src/core/lib/transport/bdp_estimator.h',
'src/core/lib/transport/call_filters.h',
'src/core/lib/transport/call_final_info.h',
'src/core/lib/transport/call_size_estimator.h',
'src/core/lib/transport/call_spine.h',
'src/core/lib/transport/connectivity_state.h',
'src/core/lib/transport/custom_metadata.h',

2
grpc.gemspec generated

@ -1905,6 +1905,8 @@ Gem::Specification.new do |s|
s.files += %w( src/core/lib/transport/call_filters.h )
s.files += %w( src/core/lib/transport/call_final_info.cc )
s.files += %w( src/core/lib/transport/call_final_info.h )
s.files += %w( src/core/lib/transport/call_size_estimator.cc )
s.files += %w( src/core/lib/transport/call_size_estimator.h )
s.files += %w( src/core/lib/transport/call_spine.cc )
s.files += %w( src/core/lib/transport/call_spine.h )
s.files += %w( src/core/lib/transport/connectivity_state.cc )

3
grpc.gyp generated

@ -1024,6 +1024,7 @@
'src/core/lib/transport/bdp_estimator.cc',
'src/core/lib/transport/call_filters.cc',
'src/core/lib/transport/call_final_info.cc',
'src/core/lib/transport/call_size_estimator.cc',
'src/core/lib/transport/call_spine.cc',
'src/core/lib/transport/connectivity_state.cc',
'src/core/lib/transport/error_utils.cc',
@ -1514,6 +1515,7 @@
'src/core/lib/transport/bdp_estimator.cc',
'src/core/lib/transport/call_filters.cc',
'src/core/lib/transport/call_final_info.cc',
'src/core/lib/transport/call_size_estimator.cc',
'src/core/lib/transport/call_spine.cc',
'src/core/lib/transport/connectivity_state.cc',
'src/core/lib/transport/error_utils.cc',
@ -2284,6 +2286,7 @@
'src/core/lib/transport/batch_builder.cc',
'src/core/lib/transport/call_filters.cc',
'src/core/lib/transport/call_final_info.cc',
'src/core/lib/transport/call_size_estimator.cc',
'src/core/lib/transport/call_spine.cc',
'src/core/lib/transport/connectivity_state.cc',
'src/core/lib/transport/error_utils.cc',

2
package.xml generated

@ -1887,6 +1887,8 @@
<file baseinstalldir="/" name="src/core/lib/transport/call_filters.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/call_final_info.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/call_final_info.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/call_size_estimator.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/call_size_estimator.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/call_spine.cc" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/call_spine.h" role="src" />
<file baseinstalldir="/" name="src/core/lib/transport/connectivity_state.cc" role="src" />

@ -6868,6 +6868,17 @@ grpc_cc_library(
],
)
grpc_cc_library(
name = "call_size_estimator",
srcs = [
"lib/transport/call_size_estimator.cc",
],
hdrs = [
"lib/transport/call_size_estimator.h",
],
deps = ["//:gpr_platform"],
)
grpc_cc_library(
name = "compression_internal",
srcs = [

@ -71,8 +71,8 @@ Channel::Channel(bool is_client, bool is_promising, std::string target,
: is_client_(is_client),
is_promising_(is_promising),
compression_options_(compression_options),
call_size_estimate_(channel_stack->call_stack_size +
grpc_call_get_initial_size_estimate()),
call_size_estimator_(channel_stack->call_stack_size +
grpc_call_get_initial_size_estimate()),
channelz_node_(channel_args.GetObjectRef<channelz::ChannelNode>()),
allocator_(channel_args.GetObject<ResourceQuota>()
->memory_quota()
@ -230,24 +230,6 @@ absl::StatusOr<RefCountedPtr<Channel>> Channel::Create(
return CreateWithBuilder(&builder);
}
void Channel::UpdateCallSizeEstimate(size_t size) {
size_t cur = call_size_estimate_.load(std::memory_order_relaxed);
if (cur < size) {
// size grew: update estimate
call_size_estimate_.compare_exchange_weak(
cur, size, std::memory_order_relaxed, std::memory_order_relaxed);
// if we lose: never mind, something else will likely update soon enough
} else if (cur == size) {
// no change: holding pattern
} else if (cur > 0) {
// size shrank: decrease estimate
call_size_estimate_.compare_exchange_weak(
cur, std::min(cur - 1, (255 * cur + size) / 256),
std::memory_order_relaxed, std::memory_order_relaxed);
// if we lose: never mind, something else will likely update soon enough
}
}
} // namespace grpc_core
char* grpc_channel_get_target(grpc_channel* channel) {

@ -55,6 +55,7 @@
#include "src/core/lib/resource_quota/memory_quota.h"
#include "src/core/lib/slice/slice.h"
#include "src/core/lib/surface/channel_stack_type.h"
#include "src/core/lib/transport/call_size_estimator.h"
#include "src/core/lib/transport/transport.h"
/// The same as grpc_channel_destroy, but doesn't create an ExecCtx, and so
@ -80,9 +81,6 @@ grpc_channel_stack* grpc_channel_get_channel_stack(grpc_channel* channel);
grpc_core::channelz::ChannelNode* grpc_channel_get_channelz_node(
grpc_channel* channel);
size_t grpc_channel_get_call_size_estimate(grpc_channel* channel);
void grpc_channel_update_call_size_estimate(grpc_channel* channel, size_t size);
namespace grpc_core {
struct RegisteredCall {
@ -124,20 +122,11 @@ class Channel : public RefCounted<Channel>,
channelz::ChannelNode* channelz_node() const { return channelz_node_.get(); }
size_t CallSizeEstimate() {
// We round up our current estimate to the NEXT value of kRoundUpSize.
// This ensures:
// 1. a consistent size allocation when our estimate is drifting slowly
// (which is common) - which tends to help most allocators reuse memory
// 2. a small amount of allowed growth over the estimate without hitting
// the arena size doubling case, reducing overall memory usage
static constexpr size_t kRoundUpSize = 256;
return (call_size_estimate_.load(std::memory_order_relaxed) +
2 * kRoundUpSize) &
~(kRoundUpSize - 1);
size_t CallSizeEstimate() { return call_size_estimator_.CallSizeEstimate(); }
void UpdateCallSizeEstimate(size_t size) {
call_size_estimator_.UpdateCallSizeEstimate(size);
}
void UpdateCallSizeEstimate(size_t size);
absl::string_view target() const { return target_; }
MemoryAllocator* allocator() { return &allocator_; }
bool is_client() const { return is_client_; }
@ -162,7 +151,7 @@ class Channel : public RefCounted<Channel>,
const bool is_client_;
const bool is_promising_;
const grpc_compression_options compression_options_;
std::atomic<size_t> call_size_estimate_;
CallSizeEstimator call_size_estimator_;
CallRegistrationTable registration_table_;
RefCountedPtr<channelz::ChannelNode> channelz_node_;
MemoryAllocator allocator_;

@ -0,0 +1,41 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <grpc/support/port_platform.h>
#include "src/core/lib/transport/call_size_estimator.h"
#include <algorithm>
namespace grpc_core {
void CallSizeEstimator::UpdateCallSizeEstimate(size_t size) {
size_t cur = call_size_estimate_.load(std::memory_order_relaxed);
if (cur < size) {
// size grew: update estimate
call_size_estimate_.compare_exchange_weak(
cur, size, std::memory_order_relaxed, std::memory_order_relaxed);
// if we lose: never mind, something else will likely update soon enough
} else if (cur == size) {
// no change: holding pattern
} else if (cur > 0) {
// size shrank: decrease estimate
call_size_estimate_.compare_exchange_weak(
cur, std::min(cur - 1, (255 * cur + size) / 256),
std::memory_order_relaxed, std::memory_order_relaxed);
// if we lose: never mind, something else will likely update soon enough
}
}
} // namespace grpc_core

@ -0,0 +1,52 @@
// Copyright 2024 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SIZE_ESTIMATOR_H
#define GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SIZE_ESTIMATOR_H
#include <grpc/support/port_platform.h>
#include <stddef.h>
#include <atomic>
namespace grpc_core {
class CallSizeEstimator {
public:
explicit CallSizeEstimator(size_t initial_estimate)
: call_size_estimate_(initial_estimate) {}
size_t CallSizeEstimate() {
// We round up our current estimate to the NEXT value of kRoundUpSize.
// This ensures:
// 1. a consistent size allocation when our estimate is drifting slowly
// (which is common) - which tends to help most allocators reuse memory
// 2. a small amount of allowed growth over the estimate without hitting
// the arena size doubling case, reducing overall memory usage
static constexpr size_t kRoundUpSize = 256;
return (call_size_estimate_.load(std::memory_order_relaxed) +
2 * kRoundUpSize) &
~(kRoundUpSize - 1);
}
void UpdateCallSizeEstimate(size_t size);
private:
std::atomic<size_t> call_size_estimate_;
};
} // namespace grpc_core
#endif // GRPC_SRC_CORE_LIB_TRANSPORT_CALL_SIZE_ESTIMATOR_H

@ -812,6 +812,7 @@ CORE_SOURCE_FILES = [
'src/core/lib/transport/bdp_estimator.cc',
'src/core/lib/transport/call_filters.cc',
'src/core/lib/transport/call_final_info.cc',
'src/core/lib/transport/call_size_estimator.cc',
'src/core/lib/transport/call_spine.cc',
'src/core/lib/transport/connectivity_state.cc',
'src/core/lib/transport/error_utils.cc',

@ -2904,6 +2904,8 @@ src/core/lib/transport/call_filters.cc \
src/core/lib/transport/call_filters.h \
src/core/lib/transport/call_final_info.cc \
src/core/lib/transport/call_final_info.h \
src/core/lib/transport/call_size_estimator.cc \
src/core/lib/transport/call_size_estimator.h \
src/core/lib/transport/call_spine.cc \
src/core/lib/transport/call_spine.h \
src/core/lib/transport/connectivity_state.cc \

@ -2685,6 +2685,8 @@ src/core/lib/transport/call_filters.cc \
src/core/lib/transport/call_filters.h \
src/core/lib/transport/call_final_info.cc \
src/core/lib/transport/call_final_info.h \
src/core/lib/transport/call_size_estimator.cc \
src/core/lib/transport/call_size_estimator.h \
src/core/lib/transport/call_spine.cc \
src/core/lib/transport/call_spine.h \
src/core/lib/transport/connectivity_state.cc \

Loading…
Cancel
Save