Skip to content

Commit 7a59bd3

Browse files
committed
refactor benchmark file structure
1 parent 2e3325f commit 7a59bd3

File tree

5 files changed

+401
-391
lines changed

5 files changed

+401
-391
lines changed

benchmark/benchmark.cpp

Lines changed: 15 additions & 147 deletions
Original file line numberDiff line numberDiff line change
@@ -6,161 +6,29 @@
66
*
77
*/
88

9-
#include <benchmark/benchmark.h>
10-
#include <umf/pools/pool_proxy.h>
11-
#ifdef UMF_POOL_SCALABLE_ENABLED
12-
#include <umf/pools/pool_scalable.h>
13-
#endif
14-
#include <umf/providers/provider_os_memory.h>
15-
16-
#ifdef UMF_POOL_DISJOINT_ENABLED
17-
#include <umf/pools/pool_disjoint.h>
18-
#endif
19-
20-
#ifdef UMF_POOL_JEMALLOC_ENABLED
21-
#include <umf/pools/pool_jemalloc.h>
22-
#endif
23-
249
#include "benchmark.hpp"
2510

26-
struct glibc_malloc : public allocator_interface {
27-
unsigned SetUp([[maybe_unused]] ::benchmark::State &state,
28-
unsigned argPos) override {
29-
return argPos;
30-
}
31-
void TearDown([[maybe_unused]] ::benchmark::State &state) override{};
32-
void *benchAlloc(size_t size) override { return malloc(size); }
33-
void benchFree(void *ptr, [[maybe_unused]] size_t size) override {
34-
free(ptr);
11+
#define UMF_BENCHMARK_TEMPLATE_DEFINE(BaseClass, Method, ...) \
12+
BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, __VA_ARGS__) \
13+
(benchmark::State & state) { \
14+
for (auto _ : state) { \
15+
bench(state); \
16+
} \
3517
}
36-
static std::string name() { return "glibc"; }
37-
};
38-
39-
struct os_provider : public provider_interface {
40-
provider_interface::params_ptr
41-
getParams(::benchmark::State &state) override {
42-
umf_os_memory_provider_params_handle_t raw_params = nullptr;
43-
umfOsMemoryProviderParamsCreate(&raw_params);
44-
if (!raw_params) {
45-
state.SkipWithError("Failed to create os provider params");
46-
return {nullptr, [](void *) {}};
47-
}
48-
49-
// Use a lambda as the custom deleter
50-
auto deleter = [](void *p) {
51-
auto handle =
52-
static_cast<umf_os_memory_provider_params_handle_t>(p);
53-
umfOsMemoryProviderParamsDestroy(handle);
54-
};
55-
56-
return {static_cast<void *>(raw_params), deleter};
57-
}
58-
59-
umf_memory_provider_ops_t *
60-
getOps([[maybe_unused]] ::benchmark::State &state) override {
61-
return umfOsMemoryProviderOps();
62-
}
63-
static std::string name() { return "os_provider"; }
64-
};
65-
66-
template <typename Provider>
67-
struct proxy_pool : public pool_interface<Provider> {
68-
umf_memory_pool_ops_t *
69-
getOps([[maybe_unused]] ::benchmark::State &state) override {
70-
return umfProxyPoolOps();
71-
}
72-
73-
static std::string name() { return "proxy_pool<" + Provider::name() + ">"; }
74-
};
7518

76-
#ifdef UMF_POOL_DISJOINT_ENABLED
77-
template <typename Provider>
78-
struct disjoint_pool : public pool_interface<Provider> {
79-
umf_memory_pool_ops_t *
80-
getOps([[maybe_unused]] ::benchmark::State &state) override {
81-
return umfDisjointPoolOps();
82-
}
83-
84-
typename pool_interface<Provider>::params_ptr
85-
getParams(::benchmark::State &state) override {
86-
umf_disjoint_pool_params_handle_t raw_params = nullptr;
87-
auto ret = umfDisjointPoolParamsCreate(&raw_params);
88-
if (ret != UMF_RESULT_SUCCESS) {
89-
state.SkipWithError("Failed to create disjoint pool params");
90-
return {nullptr, [](void *) {}};
91-
}
92-
93-
typename pool_interface<Provider>::params_ptr params(
94-
raw_params, [](void *p) {
95-
umfDisjointPoolParamsDestroy(
96-
static_cast<umf_disjoint_pool_params_handle_t>(p));
97-
});
98-
99-
ret = umfDisjointPoolParamsSetSlabMinSize(raw_params, 4096);
100-
if (ret != UMF_RESULT_SUCCESS) {
101-
state.SkipWithError("Failed to set slab min size");
102-
return {nullptr, [](void *) {}};
103-
}
104-
105-
ret = umfDisjointPoolParamsSetCapacity(raw_params, 4);
106-
if (ret != UMF_RESULT_SUCCESS) {
107-
state.SkipWithError("Failed to set capacity");
108-
return {nullptr, [](void *) {}};
109-
}
110-
111-
ret = umfDisjointPoolParamsSetMinBucketSize(raw_params, 4096);
112-
if (ret != UMF_RESULT_SUCCESS) {
113-
state.SkipWithError("Failed to set min bucket size");
114-
return {nullptr, [](void *) {}};
115-
}
116-
117-
ret = umfDisjointPoolParamsSetMaxPoolableSize(raw_params, 4096 * 16);
118-
if (ret != UMF_RESULT_SUCCESS) {
119-
state.SkipWithError("Failed to set max poolable size");
120-
return {nullptr, [](void *) {}};
121-
}
122-
123-
return params;
124-
}
125-
126-
static std::string name() {
127-
return "disjoint_pool<" + Provider::name() + ">";
128-
}
129-
};
130-
#endif
131-
132-
#ifdef UMF_POOL_JEMALLOC_ENABLED
133-
template <typename Provider>
134-
struct jemalloc_pool : public pool_interface<Provider> {
135-
umf_memory_pool_ops_t *
136-
getOps([[maybe_unused]] ::benchmark::State &state) override {
137-
return umfJemallocPoolOps();
138-
}
139-
140-
static std::string name() {
141-
return "jemalloc_pool<" + Provider::name() + ">";
142-
}
143-
};
144-
#endif
145-
146-
#ifdef UMF_POOL_SCALABLE_ENABLED
147-
template <typename Provider>
148-
struct scalable_pool : public pool_interface<Provider> {
149-
virtual umf_memory_pool_ops_t *
150-
getOps([[maybe_unused]] ::benchmark::State &state) override {
151-
return umfScalablePoolOps();
152-
}
153-
154-
static std::string name() {
155-
return "scalable_pool<" + Provider::name() + ">";
156-
}
157-
};
158-
#endif
159-
// Benchmarks scenarios:
19+
#define UMF_BENCHMARK_REGISTER_F(BaseClass, Method) \
20+
BENCHMARK_REGISTER_F(BaseClass, Method) \
21+
->ArgNames( \
22+
BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::argsName()) \
23+
->Name(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::name()) \
24+
->Iterations( \
25+
BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::iterations())
16026

16127
UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, glibc_fix, fixed_alloc_size,
16228
glibc_malloc);
16329

30+
// Benchmarks scenarios:
31+
16432
// The benchmark arguments specified in Args() are, in order:
16533
// benchmark arguments, allocator arguments, size generator arguments.
16634
// The exact meaning of each argument depends on the benchmark, allocator, and size components used.

benchmark/benchmark.hpp

Lines changed: 71 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -75,70 +75,97 @@
7575
#include <umf/memory_pool.h>
7676
#include <umf/memory_provider.h>
7777

78-
#include "benchmark_interfaces.hpp"
78+
#include "benchmark_size.hpp"
79+
#include "benchmark_umf.hpp"
7980

8081
struct alloc_data {
8182
void *ptr;
8283
size_t size;
8384
};
8485

85-
#define UMF_BENCHMARK_TEMPLATE_DEFINE(BaseClass, Method, ...) \
86-
BENCHMARK_TEMPLATE_DEFINE_F(BaseClass, Method, __VA_ARGS__) \
87-
(benchmark::State & state) { \
88-
for (auto _ : state) { \
89-
bench(state); \
90-
} \
86+
template <typename Provider, typename = std::enable_if_t<std::is_base_of<
87+
provider_interface, Provider>::value>>
88+
class provider_allocator : public allocator_interface {
89+
public:
90+
unsigned SetUp(::benchmark::State &state, unsigned r) override {
91+
provider.SetUp(state);
92+
return r;
9193
}
9294

93-
#define UMF_BENCHMARK_REGISTER_F(BaseClass, Method) \
94-
BENCHMARK_REGISTER_F(BaseClass, Method) \
95-
->ArgNames( \
96-
BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::argsName()) \
97-
->Name(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::name()) \
98-
->Iterations( \
99-
BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::iterations())
95+
void TearDown(::benchmark::State &state) override {
96+
provider.TearDown(state);
97+
}
10098

101-
class fixed_alloc_size : public alloc_size_interface {
102-
public:
103-
unsigned SetUp(::benchmark::State &state, unsigned argPos) override {
104-
size = state.range(argPos);
105-
return argPos + 1;
99+
void *benchAlloc(size_t size) override {
100+
void *ptr;
101+
if (umfMemoryProviderAlloc(provider.provider, size, 0, &ptr) !=
102+
UMF_RESULT_SUCCESS) {
103+
return NULL;
104+
}
105+
return ptr;
106+
}
107+
108+
void benchFree(void *ptr, size_t size) override {
109+
umfMemoryProviderFree(provider.provider, ptr, size);
106110
}
107-
void TearDown([[maybe_unused]] ::benchmark::State &state) override {}
108-
size_t nextSize() override { return size; };
109-
static std::vector<std::string> argsName() { return {"size"}; }
111+
112+
static std::string name() { return Provider::name(); }
110113

111114
private:
112-
size_t size;
115+
Provider provider;
113116
};
114117

115-
class uniform_alloc_size : public alloc_size_interface {
116-
using distribution = std::uniform_int_distribution<int64_t>;
117-
118+
// TODO: assert Pool to be a pool_interface<provider_interface>.
119+
template <typename Pool> class pool_allocator : public allocator_interface {
118120
public:
119-
unsigned SetUp(::benchmark::State &state, unsigned argPos) override {
120-
auto min = state.range(argPos++);
121-
auto max = state.range(argPos++);
122-
auto gran = state.range(argPos++);
123-
if (min % gran != 0 && max % gran != 0) {
124-
state.SkipWithError("min and max must be divisible by granularity");
125-
return argPos;
126-
}
121+
unsigned SetUp(::benchmark::State &state, unsigned r) override {
122+
pool.SetUp(state);
123+
return r;
124+
}
125+
126+
void TearDown(::benchmark::State &state) override { pool.TearDown(state); }
127127

128-
dist.param(distribution::param_type(min / gran, max / gran));
129-
multiplier = gran;
130-
return argPos;
128+
virtual void *benchAlloc(size_t size) override {
129+
return umfPoolMalloc(pool.pool, size);
131130
}
132-
void TearDown([[maybe_unused]] ::benchmark::State &state) override {}
133-
size_t nextSize() override { return dist(generator) * multiplier; }
134-
static std::vector<std::string> argsName() {
135-
return {"min size", "max size", "granularity"};
131+
132+
virtual void benchFree(void *ptr, [[maybe_unused]] size_t size) override {
133+
umfPoolFree(pool.pool, ptr);
136134
}
137135

136+
static std::string name() { return Pool::name(); }
137+
138138
private:
139-
std::default_random_engine generator;
140-
distribution dist;
141-
size_t multiplier;
139+
Pool pool;
140+
};
141+
142+
template <typename Size, typename Allocator>
143+
struct benchmark_interface : public benchmark::Fixture {
144+
void SetUp(::benchmark::State &state) {
145+
int argPos = alloc_size.SetUp(state, 0);
146+
allocator.SetUp(state, argPos);
147+
}
148+
149+
void TearDown(::benchmark::State &state) {
150+
alloc_size.TearDown(state);
151+
allocator.TearDown(state);
152+
}
153+
154+
virtual void bench(::benchmark::State &state) = 0;
155+
156+
static std::vector<std::string> argsName() {
157+
auto s = Size::argsName();
158+
auto a = Allocator::argsName();
159+
std::vector<std::string> res = {};
160+
res.insert(res.end(), s.begin(), s.end());
161+
res.insert(res.end(), a.begin(), a.end());
162+
return res;
163+
}
164+
165+
static std::string name() { return Allocator::name(); }
166+
static int64_t iterations() { return 10000; }
167+
Size alloc_size;
168+
Allocator allocator;
142169
};
143170

144171
// This class benchmarks speed of alloc() operations.
@@ -335,59 +362,3 @@ class multiple_malloc_free_benchmark : public alloc_benchmark<Size, Alloc> {
335362
std::default_random_engine generator;
336363
distribution dist;
337364
};
338-
339-
template <typename Provider, typename = std::enable_if_t<std::is_base_of<
340-
provider_interface, Provider>::value>>
341-
class provider_allocator : public allocator_interface {
342-
public:
343-
unsigned SetUp(::benchmark::State &state, unsigned r) override {
344-
provider.SetUp(state);
345-
return r;
346-
}
347-
348-
void TearDown(::benchmark::State &state) override {
349-
provider.TearDown(state);
350-
}
351-
352-
void *benchAlloc(size_t size) override {
353-
void *ptr;
354-
if (umfMemoryProviderAlloc(provider.provider, size, 0, &ptr) !=
355-
UMF_RESULT_SUCCESS) {
356-
return NULL;
357-
}
358-
return ptr;
359-
}
360-
361-
void benchFree(void *ptr, size_t size) override {
362-
umfMemoryProviderFree(provider.provider, ptr, size);
363-
}
364-
365-
static std::string name() { return Provider::name(); }
366-
367-
private:
368-
Provider provider;
369-
};
370-
371-
// TODO: assert Pool to be a pool_interface<provider_interface>.
372-
template <typename Pool> class pool_allocator : public allocator_interface {
373-
public:
374-
unsigned SetUp(::benchmark::State &state, unsigned r) override {
375-
pool.SetUp(state);
376-
return r;
377-
}
378-
379-
void TearDown(::benchmark::State &state) override { pool.TearDown(state); }
380-
381-
virtual void *benchAlloc(size_t size) override {
382-
return umfPoolMalloc(pool.pool, size);
383-
}
384-
385-
virtual void benchFree(void *ptr, [[maybe_unused]] size_t size) override {
386-
umfPoolFree(pool.pool, ptr);
387-
}
388-
389-
static std::string name() { return Pool::name(); }
390-
391-
private:
392-
Pool pool;
393-
};

0 commit comments

Comments
 (0)