Skip to content

Instantly share code, notes, and snippets.

@mmatrosov
Last active June 3, 2021 13:08
Show Gist options
  • Save mmatrosov/5e8688ce7ac05bc471bebaf0f6e25655 to your computer and use it in GitHub Desktop.
Save mmatrosov/5e8688ce7ac05bc471bebaf0f6e25655 to your computer and use it in GitHub Desktop.
folly::atomic_shared_ptr benchmark
#include <benchmark/benchmark.h>
#include <folly/concurrency/AtomicSharedPtr.h>
#include <shared_mutex>
#include <iostream>
struct Data {
int buffer[100];
};
int64_t g_thread_count = 1;
template <class F>
void run_test(const F& f) {
static constexpr int64_t kInvokes = 1'000'000;
const int64_t invokes_per_thread = kInvokes / g_thread_count;
std::vector<std::jthread> threads;
for (int64_t i = 0; i < g_thread_count; ++i) {
threads.emplace_back([&] {
auto ptr = std::make_shared<Data>();
for (int64_t i = 0; i < invokes_per_thread; ++i) {
f(ptr);
}
});
}
}
static void ____________mutex_store(benchmark::State& state) {
std::shared_ptr<Data> synced_ptr;
std::mutex m;
for (auto _ : state) {
run_test([&](const std::shared_ptr<Data>& ptr) {
std::unique_lock lock{m};
synced_ptr = ptr;
});
}
}
BENCHMARK(____________mutex_store)->Unit(benchmark::kMillisecond);
static void _____shared_mutex_store(benchmark::State& state) {
std::shared_ptr<Data> synced_ptr;
std::shared_mutex m;
for (auto _ : state) {
run_test([&](const std::shared_ptr<Data>& ptr) {
std::unique_lock lock{m};
synced_ptr = ptr;
});
}
}
BENCHMARK(_____shared_mutex_store)->Unit(benchmark::kMillisecond);
static void atomic_shared_ptr_store(benchmark::State& state) {
folly::atomic_shared_ptr<Data> synced_ptr;
for (auto _ : state) {
run_test([&](const std::shared_ptr<Data>& ptr) { synced_ptr = ptr; });
}
}
BENCHMARK(atomic_shared_ptr_store)->Unit(benchmark::kMillisecond);
static void ___________atomic_store(benchmark::State& state) {
std::shared_ptr<Data> synced_ptr;
for (auto _ : state) {
run_test([&](const std::shared_ptr<Data>& ptr) { std::atomic_store(&synced_ptr, ptr); });
}
}
BENCHMARK(___________atomic_store)->Unit(benchmark::kMillisecond);
static void ____________mutex_load(benchmark::State& state) {
std::shared_ptr<Data> synced_ptr;
std::mutex m;
for (auto _ : state) {
run_test([&](std::shared_ptr<Data>& ptr) {
std::unique_lock lock{m};
ptr = synced_ptr;
});
}
}
BENCHMARK(____________mutex_load)->Unit(benchmark::kMillisecond);
static void _____shared_mutex_load(benchmark::State& state) {
std::shared_ptr<Data> synced_ptr;
std::shared_mutex m;
for (auto _ : state) {
run_test([&](std::shared_ptr<Data>& ptr) {
std::shared_lock lock{m};
ptr = synced_ptr;
});
}
}
BENCHMARK(_____shared_mutex_load)->Unit(benchmark::kMillisecond);
static void atomic_shared_ptr_load(benchmark::State& state) {
folly::atomic_shared_ptr<Data> synced_ptr;
for (auto _ : state) {
run_test([&](std::shared_ptr<Data>& ptr) { ptr = synced_ptr; });
}
}
BENCHMARK(atomic_shared_ptr_load)->Unit(benchmark::kMillisecond);
static void ___________atomic_load(benchmark::State& state) {
std::shared_ptr<Data> synced_ptr;
for (auto _ : state) {
run_test([&](std::shared_ptr<Data>& ptr) { ptr = std::atomic_load(&synced_ptr); });
}
}
BENCHMARK(___________atomic_load)->Unit(benchmark::kMillisecond);
namespace {
class SilentReporter : public benchmark::ConsoleReporter {
public:
using ConsoleReporter::ConsoleReporter;
bool ReportContext(const Context&) override { return true; }
};
} // namespace
int main(int argc, char** argv) {
SilentReporter reporter;
for (auto thread_count : {1, 2, 4, 8, 12, 16}) {
g_thread_count = thread_count;
std::cout << "Running in " << g_thread_count << " threads\n";
::benchmark::Initialize(&argc, argv);
::benchmark::RunSpecifiedBenchmarks(&reporter);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment