Skip to content

reduce code duplication in Benchmark by using Apply() to set arguments #1042

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 56 additions & 75 deletions benchmark/benchmark.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
/*
* Copyright (C) 2024 Intel Corporation
* Copyright (C) 2024-2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
*/

#include <benchmark/benchmark.h>

#include "benchmark.hpp"

#define UMF_BENCHMARK_TEMPLATE_DEFINE(BaseClass, Method, ...) \
Expand All @@ -18,69 +20,65 @@

#define UMF_BENCHMARK_REGISTER_F(BaseClass, Method) \
BENCHMARK_REGISTER_F(BaseClass, Method) \
->ArgNames( \
BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::argsName()) \
->Name(BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::name()) \
->Iterations( \
BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::iterations())

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, glibc_fix, fixed_alloc_size,
glibc_malloc);
->Apply( \
&BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method)::defaultArgs)

// Benchmarks scenarios:

// The benchmark arguments specified in Args() are, in order:
// benchmark arguments, allocator arguments, size generator arguments.
// The exact meaning of each argument depends on the benchmark, allocator, and size components used.
// Refer to the 'argsName()' function in each component to find detailed descriptions of these arguments.

static void default_alloc_fix_size(benchmark::internal::Benchmark *benchmark) {
benchmark->Args({10000, 0, 4096});
benchmark->Args({10000, 100000, 4096});
benchmark->Threads(4);
benchmark->Threads(1);
}

static void
default_alloc_uniform_size(benchmark::internal::Benchmark *benchmark) {
benchmark->Args({10000, 0, 8, 64 * 1024, 8});
benchmark->Threads(4);
benchmark->Threads(1);
}

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, glibc_fix, fixed_alloc_size,
glibc_malloc);

UMF_BENCHMARK_REGISTER_F(alloc_benchmark, glibc_fix)
->Args({10000, 0, 4096})
->Args({10000, 100000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, glibc_uniform,
uniform_alloc_size, glibc_malloc);
UMF_BENCHMARK_REGISTER_F(alloc_benchmark, glibc_uniform)
->Args({10000, 0, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_uniform_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, os_provider, fixed_alloc_size,
provider_allocator<os_provider>);
UMF_BENCHMARK_REGISTER_F(alloc_benchmark, os_provider)
->Args({10000, 0, 4096})
->Args({10000, 100000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, proxy_pool, fixed_alloc_size,
pool_allocator<proxy_pool<os_provider>>);

UMF_BENCHMARK_REGISTER_F(alloc_benchmark, proxy_pool)
->Args({1000, 0, 4096})
->Args({1000, 100000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_fix_size);

#ifdef UMF_POOL_DISJOINT_ENABLED
UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, disjoint_pool_fix,
fixed_alloc_size,
pool_allocator<disjoint_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(alloc_benchmark, disjoint_pool_fix)
->Args({10000, 0, 4096})
->Args({10000, 100000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_fix_size);

// TODO: debug why this crashes
/*UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, disjoint_pool_uniform,
uniform_alloc_size,
pool_allocator<disjoint_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(alloc_benchmark, disjoint_pool_uniform)
->Args({10000, 0, 8, 64 * 1024, 8})
// ->Threads(4)
->Threads(1);
->Apply(&default_alloc_uniform_size);
*/
#endif

Expand All @@ -89,18 +87,13 @@ UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, jemalloc_pool_fix,
fixed_alloc_size,
pool_allocator<jemalloc_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(alloc_benchmark, jemalloc_pool_fix)
->Args({10000, 0, 4096})
->Args({10000, 100000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, jemalloc_pool_uniform,
uniform_alloc_size,
pool_allocator<jemalloc_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(alloc_benchmark, jemalloc_pool_uniform)
->Args({10000, 0, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_uniform_size);

#endif
#ifdef UMF_POOL_SCALABLE_ENABLED
Expand All @@ -109,71 +102,67 @@ UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, scalable_pool_fix,
pool_allocator<scalable_pool<os_provider>>);

UMF_BENCHMARK_REGISTER_F(alloc_benchmark, scalable_pool_fix)
->Args({10000, 0, 4096})
->Args({10000, 100000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(alloc_benchmark, scalable_pool_uniform,
uniform_alloc_size,
pool_allocator<scalable_pool<os_provider>>);

UMF_BENCHMARK_REGISTER_F(alloc_benchmark, scalable_pool_uniform)
->Args({10000, 0, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_alloc_uniform_size);
#endif
// Multiple allocs/free
static void
default_multiple_alloc_fix_size(benchmark::internal::Benchmark *benchmark) {
benchmark->Args({10000, 4096});
benchmark->Threads(4);
benchmark->Threads(1);
}

static void
default_multiple_alloc_uniform_size(benchmark::internal::Benchmark *benchmark) {
benchmark->Args({10000, 8, 64 * 1024, 8});
benchmark->Threads(4);
benchmark->Threads(1);
}

UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, glibc_fix,
fixed_alloc_size, glibc_malloc);

UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, glibc_fix)
->Args({10000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, glibc_uniform,
uniform_alloc_size, glibc_malloc);
UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, glibc_uniform)
->Args({10000, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_uniform_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, proxy_pool,
fixed_alloc_size,
pool_allocator<proxy_pool<os_provider>>);

UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, proxy_pool)
->Args({10000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, os_provider,
fixed_alloc_size,
provider_allocator<os_provider>);
UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, os_provider)
->Args({10000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_fix_size);

#ifdef UMF_POOL_DISJOINT_ENABLED
UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, disjoint_pool_fix,
fixed_alloc_size,
pool_allocator<disjoint_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, disjoint_pool_fix)
->Args({10000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_fix_size);

// TODO: debug why this crashes
/*UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark,
disjoint_pool_uniform, uniform_alloc_size,
pool_allocator<disjoint_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, disjoint_pool_uniform)
->Args({10000, 0, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_uniform_size);
*/
#endif

Expand All @@ -182,17 +171,13 @@ UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, jemalloc_pool_fix,
fixed_alloc_size,
pool_allocator<jemalloc_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, jemalloc_pool_fix)
->Args({10000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark,
jemalloc_pool_uniform, uniform_alloc_size,
pool_allocator<jemalloc_pool<os_provider>>);
UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, jemalloc_pool_uniform)
->Args({1000, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_uniform_size);

#endif

Expand All @@ -202,18 +187,14 @@ UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark, scalable_pool_fix,
pool_allocator<scalable_pool<os_provider>>);

UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, scalable_pool_fix)
->Args({10000, 4096})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_fix_size);

UMF_BENCHMARK_TEMPLATE_DEFINE(multiple_malloc_free_benchmark,
scalable_pool_uniform, uniform_alloc_size,
pool_allocator<scalable_pool<os_provider>>);

UMF_BENCHMARK_REGISTER_F(multiple_malloc_free_benchmark, scalable_pool_uniform)
->Args({10000, 8, 64 * 1024, 8})
->Threads(4)
->Threads(1);
->Apply(&default_multiple_alloc_uniform_size);

#endif
BENCHMARK_MAIN();
25 changes: 16 additions & 9 deletions benchmark/benchmark.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2024 Intel Corporation
* Copyright (C) 2024-2025 Intel Corporation
*
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Expand Down Expand Up @@ -162,8 +162,15 @@ struct benchmark_interface : public benchmark::Fixture {
return res;
}

static std::string name() { return Allocator::name(); }
static int64_t iterations() { return 10000; }
virtual std::string name() { return Allocator::name(); }
virtual int64_t iterations() { return 10000; }
static void defaultArgs(Benchmark *benchmark) {
auto *bench =
static_cast<benchmark_interface<Size, Allocator> *>(benchmark);
benchmark->ArgNames(bench->argsName())
->Name(bench->name())
->Iterations(bench->iterations());
}
Size alloc_size;
Allocator allocator;
};
Expand Down Expand Up @@ -260,15 +267,15 @@ class alloc_benchmark : public benchmark_interface<Size, Alloc> {
}
}

static std::vector<std::string> argsName() {
virtual std::vector<std::string> argsName() {
auto n = benchmark_interface<Size, Alloc>::argsName();
std::vector<std::string> res = {"max_allocs", "pre_allocs"};
res.insert(res.end(), n.begin(), n.end());
return res;
}

static std::string name() { return base::name() + "/alloc"; }
static int64_t iterations() { return 200000; }
virtual std::string name() { return base::name() + "/alloc"; }
virtual int64_t iterations() { return 200000; }

protected:
using base = benchmark_interface<Size, Alloc>;
Expand Down Expand Up @@ -346,18 +353,18 @@ class multiple_malloc_free_benchmark : public alloc_benchmark<Size, Alloc> {
}
}

static std::string name() {
virtual std::string name() {
return base::base::name() + "/multiple_malloc_free";
}

static std::vector<std::string> argsName() {
virtual std::vector<std::string> argsName() {
auto n = benchmark_interface<Size, Alloc>::argsName();
std::vector<std::string> res = {"max_allocs"};
res.insert(res.end(), n.begin(), n.end());
return res;
}

static int64_t iterations() { return 2000; }
virtual int64_t iterations() { return 2000; }

std::default_random_engine generator;
distribution dist;
Expand Down
Loading