Skip to content

Commit

Permalink
perf: add new BPS tree variations benchmarks
Browse files Browse the repository at this point in the history
These add three new configs to be tested in the benchmarks: tree with
child cardinalities enabled, with inner cardinality enabled and with
both of these.

NO_DOC=new benchmarks
NO_TEST=new benchmarks
NO_CHANGELOG=new benchmarks
  • Loading branch information
mkostoevr committed Apr 26, 2024
1 parent 18fc592 commit fe18854
Showing 1 changed file with 128 additions and 37 deletions.
165 changes: 128 additions & 37 deletions perf/bps_tree.cc
Expand Up @@ -4,13 +4,16 @@
#include <inttypes.h>
#include <time.h>
#include <random>
#include <memory>

#include <benchmark/benchmark.h>
#include <trivia/util.h>

#define BPS_TREE_NO_DEBUG 1

/* A simple test tree. */

#define tree_i64_EXTENT_SIZE 2048
#define tree_i64_EXTENT_SIZE 8192
#define tree_i64_elem_t int64_t
#define tree_i64_key_t int64_t
#define BPS_TREE_NAME tree_i64_t
Expand All @@ -31,6 +34,83 @@
#undef bps_tree_elem_t
#undef bps_tree_key_t

/* Tree with child cardinalities of inner blocks. */

#define BPS_INNER_CHILD_CARDS
#define treecc_i64_EXTENT_SIZE 8192
#define treecc_i64_elem_t int64_t
#define treecc_i64_key_t int64_t
#define BPS_TREE_NAME treecc_i64_t
#define BPS_TREE_BLOCK_SIZE 512
#define BPS_TREE_EXTENT_SIZE treecc_i64_EXTENT_SIZE
#define BPS_TREE_IS_IDENTICAL(a, b) ((a) == (b))
#define BPS_TREE_COMPARE(a, b, arg) ((a) - (b))
#define BPS_TREE_COMPARE_KEY(a, b, arg) ((a) - (b))
#define bps_tree_elem_t treecc_i64_elem_t
#define bps_tree_key_t treecc_i64_key_t
#include "salad/bps_tree.h"
#undef BPS_TREE_NAME
#undef BPS_TREE_BLOCK_SIZE
#undef BPS_TREE_EXTENT_SIZE
#undef BPS_TREE_IS_IDENTICAL
#undef BPS_TREE_COMPARE
#undef BPS_TREE_COMPARE_KEY
#undef bps_tree_elem_t
#undef bps_tree_key_t
#undef BPS_INNER_CHILD_CARDS

/* Tree with inner block cardinalities. */

#define BPS_INNER_CARD
#define treeic_i64_EXTENT_SIZE 8192
#define treeic_i64_elem_t int64_t
#define treeic_i64_key_t int64_t
#define BPS_TREE_NAME treeic_i64_t
#define BPS_TREE_BLOCK_SIZE 512
#define BPS_TREE_EXTENT_SIZE treeic_i64_EXTENT_SIZE
#define BPS_TREE_IS_IDENTICAL(a, b) ((a) == (b))
#define BPS_TREE_COMPARE(a, b, arg) ((a) - (b))
#define BPS_TREE_COMPARE_KEY(a, b, arg) ((a) - (b))
#define bps_tree_elem_t treeic_i64_elem_t
#define bps_tree_key_t treeic_i64_key_t
#include "salad/bps_tree.h"
#undef BPS_TREE_NAME
#undef BPS_TREE_BLOCK_SIZE
#undef BPS_TREE_EXTENT_SIZE
#undef BPS_TREE_IS_IDENTICAL
#undef BPS_TREE_COMPARE
#undef BPS_TREE_COMPARE_KEY
#undef bps_tree_elem_t
#undef bps_tree_key_t
#undef BPS_INNER_CARD

/* Tree with inner block cardinalities and child cardinalities. */

#define BPS_INNER_CHILD_CARDS
#define BPS_INNER_CARD
#define treebo_i64_EXTENT_SIZE 8192
#define treebo_i64_elem_t int64_t
#define treebo_i64_key_t int64_t
#define BPS_TREE_NAME treebo_i64_t
#define BPS_TREE_BLOCK_SIZE 512
#define BPS_TREE_EXTENT_SIZE treebo_i64_EXTENT_SIZE
#define BPS_TREE_IS_IDENTICAL(a, b) ((a) == (b))
#define BPS_TREE_COMPARE(a, b, arg) ((a) - (b))
#define BPS_TREE_COMPARE_KEY(a, b, arg) ((a) - (b))
#define bps_tree_elem_t treebo_i64_elem_t
#define bps_tree_key_t treebo_i64_key_t
#include "salad/bps_tree.h"
#undef BPS_TREE_NAME
#undef BPS_TREE_BLOCK_SIZE
#undef BPS_TREE_EXTENT_SIZE
#undef BPS_TREE_IS_IDENTICAL
#undef BPS_TREE_COMPARE
#undef BPS_TREE_COMPARE_KEY
#undef bps_tree_elem_t
#undef bps_tree_key_t
#undef BPS_INNER_CARD
#undef BPS_INNER_CHILD_CARDS

/**
* Generate the benchmark variations required.
*/
Expand All @@ -57,7 +137,10 @@

/* Meant to create specified benchmarks for all trees. */
#define generate_benchmarks(generator, func, arg) \
generator(tree_i64, func, arg)
generator(tree_i64, func, arg); \
generator(treecc_i64, func, arg); \
generator(treeic_i64, func, arg); \
generator(treebo_i64, func, arg)

/* Create size-based benchmarks for all trees. */
#define generate_benchmarks_size(func, size) \
Expand All @@ -81,16 +164,19 @@
*/
template<int EXTENT_SIZE>
class DummyAllocator {
std::vector<char> m_buf;
std::unique_ptr<char[]> m_buf;
size_t m_buf_size;
size_t m_pos = 0;

public:
DummyAllocator(size_t size)
: m_buf(((size + EXTENT_SIZE - 1) / EXTENT_SIZE) * EXTENT_SIZE)
{
/* Any BPS Tree requires 3 extents on the first insert. */
if (m_buf.size() < EXTENT_SIZE * 3)
m_buf.resize(EXTENT_SIZE * 3);
m_buf_size = ((size + EXTENT_SIZE - 1) / EXTENT_SIZE) *
EXTENT_SIZE;
/* The calculated size is incorrect for small trees. */
if (m_buf_size < EXTENT_SIZE * 10)
m_buf_size = EXTENT_SIZE * 10;
m_buf = std::unique_ptr<char[]>(new char[m_buf_size]);
}

void
Expand All @@ -105,7 +191,7 @@ class DummyAllocator {
DummyAllocator *self = (DummyAllocator *)ctx;
void *result = (void *)&self->m_buf[self->m_pos];
self->m_pos += EXTENT_SIZE;
if (unlikely(self->m_pos > self->m_buf.size())) {
if (unlikely(self->m_pos > self->m_buf_size)) {
fprintf(stderr, "Ouf of bounds allocation.\n");
exit(-1);
}
Expand Down Expand Up @@ -160,6 +246,9 @@ public: \

/* The class must be created for each instantiated BPS tree to test it. */
CREATE_TREE_CLASS(tree_i64);
CREATE_TREE_CLASS(treecc_i64);
CREATE_TREE_CLASS(treeic_i64);
CREATE_TREE_CLASS(treebo_i64);

/**
* Value generators to make key-independent benchmarks.
Expand Down Expand Up @@ -230,38 +319,42 @@ template<class tree>
static void
test_build(benchmark::State &state, size_t count)
{
std::vector<typename tree::elem_t> arr;
auto arr = std::unique_ptr<typename tree::elem_t[]>(
new typename tree::elem_t[count]);
for (size_t i = 0; i < count; i++)
arr.emplace_back(i);
arr[i] = i;

typename tree::Allocator allocator(count);
for (auto _ : state) {
typename tree::tree_t t;
tree::create(&t, 0, allocator.alloc, allocator.free,
&allocator, NULL);
tree::build(&t, &arr.front(), count);
tree::build(&t, &arr[0], count);
tree::destroy(&t);
allocator.reset();
}
}

generate_benchmarks_size(build, 1000000);
generate_benchmarks_size(build, 10000000);

template<class tree, class KeyGen>
static void
test_find(benchmark::State &state, size_t count, KeyGen kg)
{
std::vector<typename tree::elem_t> arr;
auto arr = std::unique_ptr<typename tree::elem_t[]>(
new typename tree::elem_t[count]);
for (size_t i = 0; i < count; i++)
arr.emplace_back(i);
arr[i] = i;

typename tree::Allocator allocator(count);

typename tree::tree_t t;
tree::create(&t, 0, allocator.alloc, allocator.free,
&allocator, NULL);
tree::build(&t, &arr.front(), count);
if (tree::build(&t, &arr[0], count) == -1) {
fprintf(stderr, "Tree build has failed.\n");
exit(-1);
}
for (auto _ : state)
benchmark::DoNotOptimize(tree::find(&t, kg()));
tree::destroy(&t);
Expand All @@ -275,7 +368,6 @@ test_find_first(benchmark::State &state, size_t count)
}

generate_benchmarks_size(find_first, 1000000);
generate_benchmarks_size(find_first, 10000000);

generate_benchmarks_height(find_first, 1);
generate_benchmarks_height(find_first, 2);
Expand All @@ -290,7 +382,6 @@ test_find_last(benchmark::State &state, size_t count)
}

generate_benchmarks_size(find_last, 1000000);
generate_benchmarks_size(find_last, 10000000);

generate_benchmarks_height(find_last, 1);
generate_benchmarks_height(find_last, 2);
Expand All @@ -305,7 +396,6 @@ test_find_inc(benchmark::State &state, size_t count)
}

generate_benchmarks_size(find_inc, 1000000);
generate_benchmarks_size(find_inc, 10000000);

generate_benchmarks_height(find_inc, 1);
generate_benchmarks_height(find_inc, 2);
Expand All @@ -320,7 +410,6 @@ test_find_dec(benchmark::State &state, size_t count)
}

generate_benchmarks_size(find_dec, 1000000);
generate_benchmarks_size(find_dec, 10000000);

generate_benchmarks_height(find_dec, 1);
generate_benchmarks_height(find_dec, 2);
Expand All @@ -335,7 +424,6 @@ test_find_rand(benchmark::State &state, size_t count)
}

generate_benchmarks_size(find_rand, 1000000);
generate_benchmarks_size(find_rand, 10000000);

generate_benchmarks_height(find_rand, 1);
generate_benchmarks_height(find_rand, 2);
Expand All @@ -352,16 +440,20 @@ template<class tree, class KeyGen>
static void
test_delete_insert(benchmark::State &state, size_t count, KeyGen kg)
{
std::vector<typename tree::elem_t> arr;
auto arr = std::unique_ptr<typename tree::elem_t[]>(
new typename tree::elem_t[count]);
for (size_t i = 0; i < count; i++)
arr.emplace_back(i);
arr[i] = i;

typename tree::Allocator allocator(count);

typename tree::tree_t t;
tree::create(&t, 0, allocator.alloc, allocator.free,
&allocator, NULL);
tree::build(&t, &arr.front(), count);
if (tree::build(&t, &arr[0], count) == -1) {
fprintf(stderr, "Tree build has failed.\n");
exit(-1);
}
typename tree::elem_t replaced, successor;
for (auto _ : state) {
typename tree::elem_t elem(kg());
Expand All @@ -379,7 +471,6 @@ test_delete_insert_first(benchmark::State &state, size_t count)
}

generate_benchmarks_size(delete_insert_first, 1000000);
generate_benchmarks_size(delete_insert_first, 10000000);

generate_benchmarks_height(delete_insert_first, 1);
generate_benchmarks_height(delete_insert_first, 2);
Expand All @@ -394,7 +485,6 @@ test_delete_insert_last(benchmark::State &state, size_t count)
}

generate_benchmarks_size(delete_insert_last, 1000000);
generate_benchmarks_size(delete_insert_last, 10000000);

generate_benchmarks_height(delete_insert_last, 1);
generate_benchmarks_height(delete_insert_last, 2);
Expand All @@ -409,7 +499,6 @@ test_delete_insert_inc(benchmark::State &state, size_t count)
}

generate_benchmarks_size(delete_insert_inc, 1000000);
generate_benchmarks_size(delete_insert_inc, 10000000);

generate_benchmarks_height(delete_insert_inc, 1);
generate_benchmarks_height(delete_insert_inc, 2);
Expand All @@ -424,7 +513,6 @@ test_delete_insert_dec(benchmark::State &state, size_t count)
}

generate_benchmarks_size(delete_insert_dec, 1000000);
generate_benchmarks_size(delete_insert_dec, 10000000);

generate_benchmarks_height(delete_insert_dec, 1);
generate_benchmarks_height(delete_insert_dec, 2);
Expand All @@ -439,7 +527,6 @@ test_delete_insert_rand(benchmark::State &state, size_t count)
}

generate_benchmarks_size(delete_insert_rand, 1000000);
generate_benchmarks_size(delete_insert_rand, 10000000);

generate_benchmarks_height(delete_insert_rand, 1);
generate_benchmarks_height(delete_insert_rand, 2);
Expand Down Expand Up @@ -476,7 +563,7 @@ test_insert_first(benchmark::State &state, size_t count)
test_insert<tree>(state, count, DecrementingKey(count));
}

generate_benchmarks_size_iterations(insert_first, 10000000);
generate_benchmarks_size_iterations(insert_first, 1000000);

template<class tree>
static void
Expand All @@ -485,7 +572,7 @@ test_insert_last(benchmark::State &state, size_t count)
test_insert<tree>(state, count, IncrementingKey(count));
}

generate_benchmarks_size_iterations(insert_last, 10000000);
generate_benchmarks_size_iterations(insert_last, 1000000);

template<class tree>
static void
Expand All @@ -494,22 +581,26 @@ test_insert_rand(benchmark::State &state, size_t count)
test_insert<tree>(state, count, RandomKey(count));
}

generate_benchmarks_size_iterations(insert_rand, 10000000);
generate_benchmarks_size_iterations(insert_rand, 1000000);

template<class tree, class KeyGen>
static void
test_delete(benchmark::State &state, size_t count, KeyGen kg)
{
std::vector<typename tree::elem_t> arr;
auto arr = std::unique_ptr<typename tree::elem_t[]>(
new typename tree::elem_t[count]);
for (size_t i = 0; i < count; i++)
arr.emplace_back(i);
arr[i] = i;

typename tree::Allocator allocator(count);

typename tree::tree_t t;
tree::create(&t, 0, allocator.alloc, allocator.free,
&allocator, NULL);
tree::build(&t, &arr.front(), count);
if (tree::build(&t, &arr[0], count) == -1) {
fprintf(stderr, "Tree build has failed.\n");
exit(-1);
}
for (auto _ : state)
tree::delete_(&t, kg());
tree::destroy(&t);
Expand All @@ -522,7 +613,7 @@ test_delete_first(benchmark::State &state, size_t count)
test_delete<tree>(state, count, IncrementingKey(count));
}

generate_benchmarks_size_iterations(delete_first, 10000000);
generate_benchmarks_size_iterations(delete_first, 1000000);

template<class tree>
static void
Expand All @@ -531,7 +622,7 @@ test_delete_last(benchmark::State &state, size_t count)
test_delete<tree>(state, count, DecrementingKey(count));
}

generate_benchmarks_size_iterations(delete_last, 10000000);
generate_benchmarks_size_iterations(delete_last, 1000000);

template<class tree>
static void
Expand All @@ -540,7 +631,7 @@ test_delete_rand(benchmark::State &state, size_t count)
test_delete<tree>(state, count, RandomKey(count));
}

generate_benchmarks_size_iterations(delete_rand, 10000000);
generate_benchmarks_size_iterations(delete_rand, 1000000);

BENCHMARK_MAIN();

Expand Down

0 comments on commit fe18854

Please sign in to comment.