Skip to content

Commit 48919c0

Browse files
authored
add ConcurrentSampler (#37)
1 parent 2131dc0 commit 48919c0

File tree

17 files changed

+1558
-8
lines changed

17 files changed

+1558
-8
lines changed

CMakeLists.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cmake_minimum_required(VERSION 3.14)
22

3-
project(babylon VERSION 1.2.0)
3+
project(babylon VERSION 1.2.1)
44

55
include(CTest) # for BUILD_TESTING option
66
include(CMakePackageConfigHelpers) # for write_basic_package_version_file
@@ -16,8 +16,8 @@ if(BUILD_DEPS)
1616
)
1717
FetchContent_Declare(
1818
protobuf
19-
URL "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v25.3.tar.gz"
20-
URL_HASH SHA256=d19643d265b978383352b3143f04c0641eea75a75235c111cc01a1350173180e
19+
URL "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v27.2.tar.gz"
20+
URL_HASH SHA256=e4ff2aeb767da6f4f52485c2e72468960ddfe5262483879ef6ad552e52757a77
2121
)
2222
FetchContent_Declare(
2323
boost

MODULE.bazel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module(
22
name = 'babylon',
3-
version = '1.2.0',
3+
version = '1.2.1',
44
compatibility_level = 1,
55
)
66

@@ -29,7 +29,7 @@ bazel_dep(name = 'googletest', version = '1.14.0', repo_name = 'com_google_googl
2929

3030
# --registry=file://%workspace%/registry
3131
# protobuf 25.3 is not officially support in BCR
32-
single_version_override(module_name = 'protobuf', version = '27.1')
32+
single_version_override(module_name = 'protobuf', version = '27.2')
3333
# rules_cuda latest release 0.2.1 is too old and do not have auto detect feature
3434
bazel_dep(name = 'rules_cuda', version = '0.2.2-dev', dev_dependency = True)
3535

example/use-arena-with-brpc/client.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ int main(int argc, char* argv[]) {
9494
stub.Echo(controller, &request, response,
9595
::google::protobuf::NewCallback(finish, response, controller));
9696
auto use_us = ::butil::gettimeofday_us() - begin_us;
97-
97+
9898
if (use_us < expected_us) {
9999
usleep(expected_us - use_us);
100100
}

example/use-arena-with-brpc/server.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ class EchoServiceImpl : public EchoService {
1818
google::protobuf::Closure* done) {
1919
brpc::ClosureGuard done_guard(done);
2020
response->mutable_payload()->CopyFrom(request->payload());
21-
LOG_EVERY_SECOND(INFO) << "Request SpaceUsedLong = " << request->SpaceUsedLong()
22-
<< " Response SpaceUsedLong = " << response->SpaceUsedLong();
21+
LOG_EVERY_SECOND(INFO) << "Request SpaceUsedLong = "
22+
<< request->SpaceUsedLong()
23+
<< " Response SpaceUsedLong = "
24+
<< response->SpaceUsedLong();
2325
}
2426
};
2527
} // namespace example
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
common --registry=https://bcr.bazel.build
2+
common --registry=https://baidu.github.io/babylon/registry
3+
common --registry=https://raw.githubusercontent.com/bazelboost/registry/main
4+
5+
build --compilation_mode opt --cxxopt=-std=c++17
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
7.1.2
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
cc_library(
2+
name = 'recorder',
3+
srcs = ['recorder.cpp', 'recorder.trick.cpp'],
4+
hdrs = ['recorder.h'],
5+
copts = ['-fno-access-control'],
6+
deps = [
7+
'@brpc//:bvar',
8+
'@babylon//:concurrent_counter',
9+
],
10+
)
11+
12+
cc_binary(
13+
name = 'example',
14+
srcs = ['example.cpp'],
15+
deps = [
16+
':recorder',
17+
'@brpc',
18+
'@tcmalloc//tcmalloc',
19+
],
20+
)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
bazel_dep(name = 'babylon', version = '1.2.0')
2+
bazel_dep(name = 'brpc', version = '1.9.0')
3+
bazel_dep(name = 'tcmalloc', version = '0.0.0-20240411-5ed309d')
4+
single_version_override(module_name = 'protobuf', version = '25.3')
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Use arena for brpc
2+
3+
brpc在调用用户的service前,需要在内部先完成Request和Response的实例构建和以及前后对应的正反序列化。对应的代码实现在相应的Protocol中,默认的方式实例采用动态堆内存分配模式创建,对于比较复杂的结构,内存分配释放和Message结构的构建和析构可能也会带来可见的开销。
4+
5+
利用babylon::SwissMemoryResource可以将堆内存分配该用Arena机制分配到内存池上,降低内存分配的成本且提升局部性。进一步使用babylon::ReusableManager可以在保持内存池聚集分配的局部性的同时,进一步通过尽可能复用Message结构降低构建和析构的开销。
6+
7+
下面实现了一个集成了对应功能的brpc::Protocol,演示了响应功能的使用方式,并配套对应的例子来演示性能对比。相应的Protocol实际也在baidu内部广泛使用,预期可以支持在生产环境直接使用。
8+
9+
## 示例构成
10+
11+
- `:reusable_rpc_protocol`: 独立的brpc:Protocol实现,集成了内存复用和实例复用的功能
12+
- `reusable_rpc_protocol.h`&`reusable_rpc_protocol.cpp`: 独立逻辑,和对应brpc版本无关
13+
- `reusable_rpc_protocol.trick.cpp`: 拷贝自`src/brpc/policy/baidu_rpc_protocol.cpp`并进行简要修改
14+
- `:client`&`:server`: 模拟比较复杂的Message演示性能对比
15+
16+
## 使用手册
17+
18+
```
19+
#include "reusable_rpc_protocol.h"
20+
21+
// 向brpc注册新的protocol,默认使用
22+
// protocol type = 72
23+
// protocol name = "baidu_std_reuse"
24+
if (0 != ::babylon::ReusableRPCProtocol::register_protocol()) {
25+
// 注册protocol失败
26+
}
27+
// 返回失败很可能因为type冲突,可以更换type和name
28+
if (0 != ::babylon::ReusableRPCProtocol::register_protocol(type, name)) {
29+
// 注册protocol失败
30+
}
31+
32+
// ReusableRPCProtocol协议和baidu_std相同,注册后,默认依然会走baidu_std
33+
// 需要通过显式在option中指定来启用
34+
::baidu::rpc::ServerOptions options;
35+
options.enabled_protocols = "baidu_std_reuse";
36+
37+
// 下面正常注册服务,启动服务器即可
38+
class SomeServiceImpl : public SomeService {
39+
public:
40+
virtual void some_method(::google::protobuf::RpcController* controller,
41+
const SomeRequest* request,
42+
SomeResponse* response,
43+
::google::protobuf::Closure* done) {
44+
... // 正常进行业务处理,对应的request和response已经改用内存池或者实例复用托管了
45+
}
46+
};
47+
48+
// 影响运行时的flag
49+
// --babylon_rpc_full_reuse,是否启用实例重用,默认false
50+
// --babylon_rpc_closure_cache_num,内存池和ReusableManager实例本身也会通过对象池复用,设置对象池大小
51+
// --babylon_rpc_page_size,内存池单页大小,超过单页大小的申请会直接改为动态申请
52+
// --babylon_rpc_page_cache_num,内存池页本身通过对象池复用,设置对象池大小
53+
```
54+
55+
## 性能演示
56+
57+
CPU: AMD EPYC 7W83 64-Core Processor, taskset 0-3 core
58+
QPS: 750
59+
60+
- 原始模式
61+
- latency_percentiles: "[1923,2222,2944,3447]"
62+
- process_cpu_usage : 1.489
63+
- process_memory_resident : 59244544
64+
- `--use_arena`模式
65+
- latency_percentiles: "[1378,1607,2263,2716]"
66+
- process_cpu_usage : 0.695
67+
- process_memory_resident : 54255616
68+
- `--use_arena`&`--babylon_rpc_full_reuse`模式
69+
- latency_percentiles: "[1096,1256,1612,1938]"
70+
- process_cpu_usage : 0.612
71+
- process_memory_resident : 101576704
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
#!/bin/sh
2+
set -ex
3+
4+
bazel build example

0 commit comments

Comments
 (0)