diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:54:28 +0000 |
commit | e6918187568dbd01842d8d1d2c808ce16a894239 (patch) | |
tree | 64f88b554b444a49f656b6c656111a145cbbaa28 /src/jaegertracing/opentelemetry-cpp/sdk/test/common/circular_buffer_benchmark.cc | |
parent | Initial commit. (diff) | |
download | ceph-e6918187568dbd01842d8d1d2c808ce16a894239.tar.xz ceph-e6918187568dbd01842d8d1d2c808ce16a894239.zip |
Adding upstream version 18.2.2.upstream/18.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/jaegertracing/opentelemetry-cpp/sdk/test/common/circular_buffer_benchmark.cc')
-rw-r--r-- | src/jaegertracing/opentelemetry-cpp/sdk/test/common/circular_buffer_benchmark.cc | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/src/jaegertracing/opentelemetry-cpp/sdk/test/common/circular_buffer_benchmark.cc b/src/jaegertracing/opentelemetry-cpp/sdk/test/common/circular_buffer_benchmark.cc new file mode 100644 index 000000000..1f2b9b42c --- /dev/null +++ b/src/jaegertracing/opentelemetry-cpp/sdk/test/common/circular_buffer_benchmark.cc @@ -0,0 +1,133 @@ +// Copyright The OpenTelemetry Authors +// SPDX-License-Identifier: Apache-2.0 + +#include "benchmark/benchmark.h" + +#include <atomic> +#include <cstdint> +#include <iostream> +#include <memory> +#include <random> +#include <thread> +#include <vector> + +#include "opentelemetry/sdk/common/circular_buffer.h" +#include "test/common/baseline_circular_buffer.h" +using opentelemetry::sdk::common::AtomicUniquePtr; +using opentelemetry::sdk::common::CircularBuffer; +using opentelemetry::sdk::common::CircularBufferRange; +using opentelemetry::testing::BaselineCircularBuffer; + +const int N = 10000; + +static uint64_t ConsumeBufferNumbers(BaselineCircularBuffer<uint64_t> &buffer) noexcept +{ + uint64_t result = 0; + buffer.Consume([&](std::unique_ptr<uint64_t> &&x) { + result += *x; + x.reset(); + }); + return result; +} + +static uint64_t ConsumeBufferNumbers(CircularBuffer<uint64_t> &buffer) noexcept +{ + uint64_t result = 0; + buffer.Consume(buffer.size(), + [&](CircularBufferRange<AtomicUniquePtr<uint64_t>> &range) noexcept { + range.ForEach([&](AtomicUniquePtr<uint64_t> &ptr) noexcept { + result += *ptr; + ptr.Reset(); + return true; + }); + }); + return result; +} + +template <class Buffer> +static void GenerateNumbersForThread(Buffer &buffer, int n, std::atomic<uint64_t> &sum) noexcept +{ + thread_local std::mt19937_64 random_number_generator{std::random_device{}()}; + for (int i = 0; i < n; ++i) + { + auto x = random_number_generator(); + std::unique_ptr<uint64_t> element{new uint64_t{x}}; + if (buffer.Add(element)) + { + sum += x; + } + } +} + +template <class Buffer> +static uint64_t GenerateNumbers(Buffer &buffer, int num_threads, int n) noexcept +{ + std::atomic<uint64_t> sum{0}; + std::vector<std::thread> threads(num_threads); + for (auto &thread : threads) + { + thread = std::thread{GenerateNumbersForThread<Buffer>, std::ref(buffer), n, std::ref(sum)}; + } + for (auto &thread : threads) + { + thread.join(); + } + return sum; +} + +template <class Buffer> +static void ConsumeNumbers(Buffer &buffer, uint64_t &sum, std::atomic<bool> &finished) noexcept +{ + while (!finished) + { + sum += ConsumeBufferNumbers(buffer); + } + sum += ConsumeBufferNumbers(buffer); +} + +template <class Buffer> +static void RunSimulation(Buffer &buffer, int num_threads, int n) noexcept +{ + std::atomic<bool> finished{false}; + uint64_t consumer_sum{0}; + std::thread consumer_thread{ConsumeNumbers<Buffer>, std::ref(buffer), std::ref(consumer_sum), + std::ref(finished)}; + uint64_t producer_sum = GenerateNumbers(buffer, num_threads, n); + finished = true; + consumer_thread.join(); + if (consumer_sum != producer_sum) + { + std::cerr << "Sumulation failed: consumer_sum != producer_sum\n"; + std::terminate(); + } +} + +static void BM_BaselineBuffer(benchmark::State &state) +{ + const size_t max_elements = 500; + const int num_threads = static_cast<int>(state.range(0)); + const int n = static_cast<int>(N / num_threads); + BaselineCircularBuffer<uint64_t> buffer{max_elements}; + for (auto _ : state) + { + RunSimulation(buffer, num_threads, n); + } +} + +BENCHMARK(BM_BaselineBuffer)->Arg(1)->Arg(2)->Arg(4); + +static void BM_LockFreeBuffer(benchmark::State &state) +{ + const size_t max_elements = 500; + const int num_threads = static_cast<int>(state.range(0)); + const int n = static_cast<int>(N / num_threads); + CircularBuffer<uint64_t> buffer{max_elements}; + for (auto _ : state) + { + RunSimulation(buffer, num_threads, n); + } +} + +BENCHMARK(BM_LockFreeBuffer)->Arg(1)->Arg(2)->Arg(4); + +BENCHMARK_MAIN(); |