From 97a30171cb8a772741a9a58f92b9df47e9ca21d6 Mon Sep 17 00:00:00 2001 From: Derek Bailey Date: Mon, 15 Nov 2021 15:19:03 -0800 Subject: Added Raw C++ benchmarks (#6924) --- benchmarks/CMakeLists.txt | 5 +- benchmarks/cpp/benchmark_main.cpp | 87 +++++++++++++++++-------- benchmarks/cpp/flatbuffers/fb_bench.cpp | 19 +++--- benchmarks/cpp/raw/raw_bench.cpp | 109 ++++++++++++++++++++++++++++++++ benchmarks/cpp/raw/raw_bench.h | 10 +++ 5 files changed, 191 insertions(+), 39 deletions(-) create mode 100644 benchmarks/cpp/raw/raw_bench.cpp create mode 100644 benchmarks/cpp/raw/raw_bench.h (limited to 'benchmarks') diff --git a/benchmarks/CMakeLists.txt b/benchmarks/CMakeLists.txt index d20464b3..3d3032c6 100644 --- a/benchmarks/CMakeLists.txt +++ b/benchmarks/CMakeLists.txt @@ -29,15 +29,14 @@ FetchContent_MakeAvailable( set(CPP_BENCH_DIR cpp) set(CPP_FB_BENCH_DIR ${CPP_BENCH_DIR}/flatbuffers) +set(CPP_RAW_BENCH_DIR ${CPP_BENCH_DIR}/raw) set(CPP_BENCH_FBS ${CPP_FB_BENCH_DIR}/bench.fbs) set(CPP_BENCH_FB_GEN ${CPP_FB_BENCH_DIR}/bench_generated.h) set(FlatBenchmark_SRCS ${CPP_BENCH_DIR}/benchmark_main.cpp - ${CPP_BENCH_DIR}/bench.h ${CPP_FB_BENCH_DIR}/fb_bench.cpp - ${CPP_FB_BENCH_DIR}/fb_bench.h - ${CPP_BENCH_FB_GEN} + ${CPP_RAW_BENCH_DIR}/raw_bench.cpp ) # Generate the flatbuffers benchmark code from the flatbuffers schema using diff --git a/benchmarks/cpp/benchmark_main.cpp b/benchmarks/cpp/benchmark_main.cpp index 8ace5ac4..720f94e6 100644 --- a/benchmarks/cpp/benchmark_main.cpp +++ b/benchmarks/cpp/benchmark_main.cpp @@ -3,20 +3,48 @@ #include "benchmarks/cpp/bench.h" #include "benchmarks/cpp/flatbuffers/fb_bench.h" +#include "benchmarks/cpp/raw/raw_bench.h" + +static inline void Encode(benchmark::State &state, + std::unique_ptr &bench, uint8_t *buffer) { + int64_t length; + for (auto _ : state) { + bench->Encode(buffer, length); + benchmark::DoNotOptimize(length); + } +} + +static inline void Decode(benchmark::State &state, + std::unique_ptr &bench, uint8_t *buffer) { + int64_t length; + uint8_t *encoded = bench->Encode(buffer, length); + + for (auto _ : state) { + void *decoded = bench->Decode(encoded, length); + benchmark::DoNotOptimize(decoded); + } +} + +static inline void Use(benchmark::State &state, std::unique_ptr &bench, + uint8_t *buffer, int64_t check_sum) { + int64_t length; + uint8_t *encoded = bench->Encode(buffer, length); + void *decoded = bench->Decode(encoded, length); + + int64_t sum = 0; + + for (auto _ : state) { sum = bench->Use(decoded); } + + EXPECT_EQ(sum, check_sum); +} static void BM_Flatbuffers_Encode(benchmark::State &state) { const int64_t kBufferLength = 1024; uint8_t buffer[kBufferLength]; - int64_t length; - StaticAllocator allocator(&buffer[0]); std::unique_ptr bench = NewFlatBuffersBench(kBufferLength, &allocator); - - for (auto _ : state) { - bench->Encode(buffer, length); - benchmark::DoNotOptimize(length); - } + Encode(state, bench, buffer); } BENCHMARK(BM_Flatbuffers_Encode); @@ -24,17 +52,9 @@ static void BM_Flatbuffers_Decode(benchmark::State &state) { const int64_t kBufferLength = 1024; uint8_t buffer[kBufferLength]; - int64_t length; - StaticAllocator allocator(&buffer[0]); std::unique_ptr bench = NewFlatBuffersBench(kBufferLength, &allocator); - - uint8_t* encoded = bench->Encode(buffer, length); - - for (auto _ : state) { - void* decoded = bench->Decode(encoded, length); - benchmark::DoNotOptimize(decoded); - } + Decode(state, bench, buffer); } BENCHMARK(BM_Flatbuffers_Decode); @@ -42,20 +62,35 @@ static void BM_Flatbuffers_Use(benchmark::State &state) { const int64_t kBufferLength = 1024; uint8_t buffer[kBufferLength]; - int64_t length; - StaticAllocator allocator(&buffer[0]); std::unique_ptr bench = NewFlatBuffersBench(kBufferLength, &allocator); + Use(state, bench, buffer, 218812692406581874); +} +BENCHMARK(BM_Flatbuffers_Use); - uint8_t* encoded = bench->Encode(buffer, length); - void* decoded = bench->Decode(encoded, length); +static void BM_Raw_Encode(benchmark::State &state) { + const int64_t kBufferLength = 1024; + uint8_t buffer[kBufferLength]; - int64_t sum = 0; + std::unique_ptr bench = NewRawBench(); + Encode(state, bench, buffer); +} +BENCHMARK(BM_Raw_Encode); - for (auto _ : state) { - sum = bench->Use(decoded); - } +static void BM_Raw_Decode(benchmark::State &state) { + const int64_t kBufferLength = 1024; + uint8_t buffer[kBufferLength]; + + std::unique_ptr bench = NewRawBench(); + Decode(state, bench, buffer); +} +BENCHMARK(BM_Raw_Decode); + +static void BM_Raw_Use(benchmark::State &state) { + const int64_t kBufferLength = 1024; + uint8_t buffer[kBufferLength]; - EXPECT_EQ(sum , 218812692406581874); + std::unique_ptr bench = NewRawBench(); + Use(state, bench, buffer, 218812692406581874); } -BENCHMARK(BM_Flatbuffers_Use); \ No newline at end of file +BENCHMARK(BM_Raw_Use); \ No newline at end of file diff --git a/benchmarks/cpp/flatbuffers/fb_bench.cpp b/benchmarks/cpp/flatbuffers/fb_bench.cpp index 08dc0df7..2bbb9a53 100644 --- a/benchmarks/cpp/flatbuffers/fb_bench.cpp +++ b/benchmarks/cpp/flatbuffers/fb_bench.cpp @@ -13,35 +13,34 @@ using namespace benchmarks_flatbuffers; namespace { struct FlatBufferBench : Bench { - explicit FlatBufferBench(int64_t initial_size, - Allocator *allocator) + explicit FlatBufferBench(int64_t initial_size, Allocator *allocator) : fbb(initial_size, allocator, false) {} - uint8_t *Encode(void *, int64_t &len) override { + uint8_t *Encode(void *, int64_t &len) { fbb.Clear(); const int kVectorLength = 3; Offset vec[kVectorLength]; - for(int i = 0; i < kVectorLength; ++i) { + for (int i = 0; i < kVectorLength; ++i) { Foo foo(0xABADCAFEABADCAFE + i, 10000 + i, '@' + i, 1000000 + i); Bar bar(foo, 123456 + i, 3.14159f + i, 10000 + i); auto name = fbb.CreateString("Hello, World!"); - auto foobar = CreateFooBar(fbb, &bar, name, 3.1415432432445543543 + i, - '!' + i); + auto foobar = + CreateFooBar(fbb, &bar, name, 3.1415432432445543543 + i, '!' + i); vec[i] = foobar; } auto location = fbb.CreateString("http://google.com/flatbuffers/"); auto foobarvec = fbb.CreateVector(vec, kVectorLength); - auto foobarcontainer = CreateFooBarContainer(fbb, foobarvec, true, - Enum_Bananas, location); + auto foobarcontainer = + CreateFooBarContainer(fbb, foobarvec, true, Enum_Bananas, location); fbb.Finish(foobarcontainer); len = fbb.GetSize(); return fbb.GetBufferPointer(); } - int64_t Use(void *decoded) override { + int64_t Use(void *decoded) { sum = 0; auto foobarcontainer = GetFooBarContainer(decoded); sum = 0; @@ -66,7 +65,7 @@ struct FlatBufferBench : Bench { return sum; } - void *Decode(void *buffer, int64_t) override { return buffer; } + void *Decode(void *buffer, int64_t) { return buffer; } void Dealloc(void *) override{}; FlatBufferBuilder fbb; diff --git a/benchmarks/cpp/raw/raw_bench.cpp b/benchmarks/cpp/raw/raw_bench.cpp new file mode 100644 index 00000000..810cb1f4 --- /dev/null +++ b/benchmarks/cpp/raw/raw_bench.cpp @@ -0,0 +1,109 @@ +#include "benchmarks/cpp/raw/raw_bench.h" + +#include +#include +#include + +#include "benchmarks/cpp/bench.h" + +namespace { +const int64_t kStringLength = 32; +const int64_t kVectorLength = 3; + +enum Enum { Apples, Pears, Bananas }; + +struct Foo { + int64_t id; + short count; + char prefix; + int length; +}; + +struct Bar { + Foo parent; + int time; + float ratio; + unsigned short size; +}; + +struct FooBar { + Bar sibling; + // We have to stick this in, otherwise strlen() will make it slower than + // FlatBuffers: + int name_len; + char name[kStringLength]; + double rating; + unsigned char postfix; +}; + +struct FooBarContainer { + FooBar list[kVectorLength]; // 3 copies of the above + bool initialized; + Enum fruit; + int location_len; + char location[kStringLength]; +}; + +struct RawBench : Bench { + uint8_t *Encode(void *buf, int64_t &len) { + FooBarContainer *fbc = new (buf) FooBarContainer; + strcpy(fbc->location, "http://google.com/flatbuffers/"); // Unsafe eek! + fbc->location_len = (int)strlen(fbc->location); + fbc->fruit = Bananas; + fbc->initialized = true; + for (int i = 0; i < kVectorLength; i++) { + // We add + i to not make these identical copies for a more realistic + // compression test. + auto &foobar = fbc->list[i]; + foobar.rating = 3.1415432432445543543 + i; + foobar.postfix = '!' + i; + strcpy(foobar.name, "Hello, World!"); + foobar.name_len = (int)strlen(foobar.name); + auto &bar = foobar.sibling; + bar.ratio = 3.14159f + i; + bar.size = 10000 + i; + bar.time = 123456 + i; + auto &foo = bar.parent; + foo.id = 0xABADCAFEABADCAFE + i; + foo.count = 10000 + i; + foo.length = 1000000 + i; + foo.prefix = '@' + i; + } + + len = sizeof(FooBarContainer); + return reinterpret_cast(fbc); + }; + + int64_t Use(void *decoded) { + auto foobarcontainer = reinterpret_cast(decoded); + sum = 0; + Add(foobarcontainer->initialized); + Add(foobarcontainer->location_len); + Add(foobarcontainer->fruit); + for (unsigned int i = 0; i < kVectorLength; i++) { + auto foobar = &foobarcontainer->list[i]; + Add(foobar->name_len); + Add(foobar->postfix); + Add(static_cast(foobar->rating)); + auto bar = &foobar->sibling; + Add(static_cast(bar->ratio)); + Add(bar->size); + Add(bar->time); + auto &foo = bar->parent; + Add(foo.count); + Add(foo.id); + Add(foo.length); + Add(foo.prefix); + } + return sum; + } + + void *Decode(void *buf, int64_t) { return buf; } + void Dealloc(void *) override{}; +}; + +} // namespace + +std::unique_ptr NewRawBench() { + return std::unique_ptr(new RawBench()); +} diff --git a/benchmarks/cpp/raw/raw_bench.h b/benchmarks/cpp/raw/raw_bench.h new file mode 100644 index 00000000..68bb278c --- /dev/null +++ b/benchmarks/cpp/raw/raw_bench.h @@ -0,0 +1,10 @@ +#ifndef BENCHMARKS_CPP_RAW_RAW_BENCH_H_ +#define BENCHMARKS_CPP_RAW_RAW_BENCH_H_ + +#include + +#include "benchmarks/cpp/bench.h" + +std::unique_ptr NewRawBench(); + +#endif // BENCHMARKS_CPP_RAW_RAW_BENCH_H_ \ No newline at end of file -- cgit v1.2.3