Add benchmarks for getChild{L,G}eq
This commit is contained in:
2
.clangd
2
.clangd
@@ -1,2 +1,2 @@
|
|||||||
CompileFlags:
|
CompileFlags:
|
||||||
Add: [-DENABLE_MAIN, -UNDEBUG, -DENABLE_FUZZ]
|
Add: [-DENABLE_MAIN, -UNDEBUG, -DENABLE_FUZZ, -fexceptions]
|
||||||
|
@@ -82,8 +82,8 @@ target_compile_definitions(conflict_set_main PRIVATE ENABLE_MAIN)
|
|||||||
set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined")
|
set(FUZZ_FLAGS "-fsanitize=fuzzer-no-link,address,undefined")
|
||||||
include(CheckCXXCompilerFlag)
|
include(CheckCXXCompilerFlag)
|
||||||
cmake_push_check_state()
|
cmake_push_check_state()
|
||||||
set(CMAKE_REQUIRED_LINK_OPTIONS -fsanitize=fuzzer)
|
set(CMAKE_REQUIRED_LINK_OPTIONS -fsanitize=fuzzer-no-link)
|
||||||
check_cxx_compiler_flag(-fsanitize=fuzzer HAS_LIB_FUZZER)
|
check_cxx_compiler_flag(-fsanitize=fuzzer-no-link HAS_LIB_FUZZER)
|
||||||
cmake_pop_check_state()
|
cmake_pop_check_state()
|
||||||
|
|
||||||
if(HAS_LIB_FUZZER)
|
if(HAS_LIB_FUZZER)
|
||||||
|
@@ -411,8 +411,7 @@ int getChildLeq(Node *self, int child) {
|
|||||||
#endif
|
#endif
|
||||||
} else if (self->type == Type::Node48) {
|
} else if (self->type == Type::Node48) {
|
||||||
auto *self48 = static_cast<Node48 *>(self);
|
auto *self48 = static_cast<Node48 *>(self);
|
||||||
// TODO the plain loop is faster?
|
#if defined(HAS_AVX) || defined(HAS_ARM_NEON)
|
||||||
#if 0 && (defined(HAS_AVX) || defined(HAS_ARM_NEON))
|
|
||||||
int i = child;
|
int i = child;
|
||||||
if (i < 0) {
|
if (i < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
@@ -736,6 +735,24 @@ void insert(Node **self_, std::span<const uint8_t> key, int64_t writeVersion) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void destroyTree(Node *root) {
|
||||||
|
Arena arena;
|
||||||
|
auto toFree = vector<Node *>(arena);
|
||||||
|
toFree.push_back(root);
|
||||||
|
while (toFree.size() > 0) {
|
||||||
|
auto *n = toFree.back();
|
||||||
|
toFree.pop_back();
|
||||||
|
// Add all children to toFree
|
||||||
|
for (int child = getChildGeq(n, 0); child >= 0;
|
||||||
|
child = getChildGeq(n, child + 1)) {
|
||||||
|
auto *c = getChildExists(n, child);
|
||||||
|
assert(c != nullptr);
|
||||||
|
toFree.push_back(c);
|
||||||
|
}
|
||||||
|
free(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||||
void check(const ReadRange *reads, Result *result, int count) const {
|
void check(const ReadRange *reads, Result *result, int count) const {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
@@ -781,23 +798,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
root->entry.rangeVersion = oldestVersion;
|
root->entry.rangeVersion = oldestVersion;
|
||||||
root->entryPresent = true;
|
root->entryPresent = true;
|
||||||
}
|
}
|
||||||
~Impl() {
|
~Impl() { destroyTree(root); }
|
||||||
Arena arena;
|
|
||||||
auto toFree = vector<Node *>(arena);
|
|
||||||
toFree.push_back(root);
|
|
||||||
while (toFree.size() > 0) {
|
|
||||||
auto *n = toFree.back();
|
|
||||||
toFree.pop_back();
|
|
||||||
// Add all children to toFree
|
|
||||||
for (int child = getChildGeq(n, 0); child >= 0;
|
|
||||||
child = getChildGeq(n, child + 1)) {
|
|
||||||
auto *c = getChildExists(n, child);
|
|
||||||
assert(c != nullptr);
|
|
||||||
toFree.push_back(c);
|
|
||||||
}
|
|
||||||
free(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Node *root;
|
Node *root;
|
||||||
int64_t oldestVersion;
|
int64_t oldestVersion;
|
||||||
@@ -991,21 +992,33 @@ void __throw_length_error(const char *) { __builtin_unreachable(); }
|
|||||||
} // namespace std
|
} // namespace std
|
||||||
|
|
||||||
#ifdef ENABLE_MAIN
|
#ifdef ENABLE_MAIN
|
||||||
int main(void) {
|
#define ANKERL_NANOBENCH_IMPLEMENT
|
||||||
int64_t writeVersion = 0;
|
#include "third_party/nanobench.h"
|
||||||
ConflictSet::Impl cs{writeVersion};
|
|
||||||
ReferenceImpl refImpl{writeVersion};
|
void bench() {
|
||||||
Arena arena;
|
ankerl::nanobench::Bench bench;
|
||||||
constexpr int kNumKeys = 10;
|
{
|
||||||
auto *write = new (arena) ConflictSet::WriteRange[kNumKeys];
|
auto *n = newNode();
|
||||||
for (int i = 0; i < kNumKeys; ++i) {
|
for (int i = 0; i < 64; ++i) {
|
||||||
write[i].begin = toKey(arena, i);
|
getOrCreateChild(n, i) = newNode();
|
||||||
write[i].end.len = 0;
|
bench.run("getChildLeq" + std::to_string(i),
|
||||||
write[i].writeVersion = ++writeVersion;
|
[&]() { bench.doNotOptimizeAway(getChildLeq(n, 255)); });
|
||||||
|
}
|
||||||
|
destroyTree(n);
|
||||||
}
|
}
|
||||||
cs.addWrites(write, kNumKeys);
|
{
|
||||||
refImpl.addWrites(write, kNumKeys);
|
auto *n = newNode();
|
||||||
debugPrintDot(stdout, cs.root);
|
for (int i = 255; i >= 3 * 64; --i) {
|
||||||
|
getOrCreateChild(n, i) = newNode();
|
||||||
|
bench.run("getChildGeq" + std::to_string(i),
|
||||||
|
[&]() { bench.doNotOptimizeAway(getChildGeq(n, 0)); });
|
||||||
|
}
|
||||||
|
destroyTree(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
bench();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Reference in New Issue
Block a user