-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbenchmark_tcmalloc.cpp
More file actions
114 lines (95 loc) · 4 KB
/
Copy pathbenchmark_tcmalloc.cpp
File metadata and controls
114 lines (95 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <benchmark/benchmark.h>
#include "TCMallocator.h"
#include <vector>
#include <random>
#include <thread>
// ==========================================
// 场景一:单一固定小对象高频申请释放 (微基准)
// ==========================================
static void BM_TCMalloc_FixedSmall(benchmark::State& state) {
const std::size_t alloc_size = state.range(0);
TCMallocator& allocator = TCMallocator::instance();
for (auto _ : state) {
void* ptr = allocator.allocate(alloc_size);
benchmark::DoNotOptimize(ptr); // 防止编译器过度优化
allocator.deallocate(ptr);
}
}
// 测试 32 字节、256 字节、4KB 三种典型小/中对象
BENCHMARK(BM_TCMalloc_FixedSmall)->Arg(32)->Arg(256)->Arg(4096)->Threads(1)->Threads(8);
// ==========================================
// 场景二:混合动态大小模拟真实业务 (Mixed Payload)
// ==========================================
// 预先生成一组大小各异的申请请求(涵盖 16B 到 64KB 各种档位),模拟真实应用场景
static void BM_TCMalloc_MixedWorkload(benchmark::State& state) {
TCMallocator& allocator = TCMallocator::instance();
// 固定的混合尺寸序列(模拟真实业务碎片化分配)
const std::vector<std::size_t> sizes = {
16, 24, 32, 48, 64, 128, 256, 384, 512, 1024,
2048, 4096, 8192, 16384, 32768, 65536
};
const std::size_t kNumSlots = 1024;
std::vector<void*> ptrs(kNumSlots, nullptr);
// 随机数引擎用于模拟真实的动态分配模式
std::mt19937 rng(1337);
std::uniform_int_distribution<std::size_t> dist(0, sizes.size() - 1);
std::uniform_int_distribution<std::size_t> slot_dist(0, kNumSlots - 1);
for (auto _ : state) {
// 随机挑选一个槽位进行 “先释放再申请” 或直接替换
std::size_t slot = slot_dist(rng);
if (ptrs[slot] != nullptr) {
allocator.deallocate(ptrs[slot]);
}
std::size_t size = sizes[dist(rng)];
ptrs[slot] = allocator.allocate(size);
benchmark::DoNotOptimize(ptrs[slot]);
}
// 清理残留
for (void* p : ptrs) {
if (p) allocator.deallocate(p);
}
}
BENCHMARK(BM_TCMalloc_MixedWorkload)->Threads(1)->Threads(4)->Threads(8)->Threads(16);
// ==========================================
// 场景三:大对象直接分配压测 (> 256KB)
// ==========================================
static void BM_TCMalloc_LargeObject(benchmark::State& state) {
std::size_t size = state.range(0);
TCMallocator& allocator = TCMallocator::instance();
for (auto _ : state) {
void* ptr = allocator.allocate(size);
benchmark::DoNotOptimize(ptr);
allocator.deallocate(ptr);
}
}
// 测试 512KB 和 2MB 的大对象分配(触发 PageHeap / mmap 路径)
BENCHMARK(BM_TCMalloc_LargeObject)->Arg(512 * 1024)->Arg(2 * 1024 * 1024)->Threads(1)->Threads(4);
// ==========================================
// 场景四:对比系统原生的 malloc / free 作为基准参照
// ==========================================
static void BM_SystemMalloc_Mixed(benchmark::State& state) {
const std::vector<std::size_t> sizes = {
16, 32, 64, 128, 256, 512, 1024, 4096, 16384
};
const std::size_t kNumSlots = 1024;
std::vector<void*> ptrs(kNumSlots, nullptr);
std::mt19937 rng(1337);
std::uniform_int_distribution<std::size_t> dist(0, sizes.size() - 1);
std::uniform_int_distribution<std::size_t> slot_dist(0, kNumSlots - 1);
for (auto _ : state) {
std::size_t slot = slot_dist(rng);
if (ptrs[slot] != nullptr) {
std::free(ptrs[slot]);
}
std::size_t size = sizes[dist(rng)];
ptrs[slot] = std::malloc(size);
benchmark::DoNotOptimize(ptrs[slot]);
}
for (void* p : ptrs) {
if (p) std::free(p);
}
}
// 开启多线程与 TCMalloc 进行横向对比
BENCHMARK(BM_SystemMalloc_Mixed)->Threads(1)->Threads(4)->Threads(8)->Threads(16);
// 程序的入口
BENCHMARK_MAIN();