cachelib/benchmarks/tl-bench/main.cpp (123 lines of code) (raw):

/* * Copyright (c) Facebook, Inc. and its affiliates. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <folly/Benchmark.h> #include <atomic> #include <thread> #include <vector> #include "cachelib/common/AtomicCounter.h" #include "cachelib/common/FastStats.h" /* Current results ============================================================================ cachelib/benchmarks/tl-bench/main.cpp relative time/iter iters/s ============================================================================ atomic_inc_single 168.31ms 5.94 fast_stats_single 5360.73% 3.14ms 318.50 ---------------------------------------------------------------------------- fast_stats_many 3.23ms 309.83 fast_stats_many_repeated 75.29% 4.29ms 233.28 tl_counter_many 74.01% 4.36ms 229.30 atomic_many 0.37% 870.86ms 1.15 ============================================================================ */ size_t nThreads = 64; size_t nOps = 100000; using facebook::cachelib::AtomicCounter; using facebook::cachelib::TLCounter; using facebook::cachelib::util::FastStats; void runInThreads(size_t numThreads, const std::function<void()>& f) { std::vector<std::thread> threads; for (size_t i = 0; i < numThreads; i++) { threads.push_back(std::thread(f)); } for (auto& t : threads) { t.join(); } } BENCHMARK(atomic_inc_single) { AtomicCounter v{0}; auto f = [&]() { for (size_t i = 0; i < nOps; i++) { v.inc(); } }; runInThreads(nThreads, f); } BENCHMARK_RELATIVE(fast_stats_single) { FastStats<uint64_t> v; auto f = [&]() { for (size_t i = 0; i < nOps; i++) { v.tlStats()++; } }; runInThreads(nThreads, f); } BENCHMARK_DRAW_LINE(); namespace { struct ManyFastStats { FastStats<uint64_t> a{}; FastStats<uint64_t> b{}; FastStats<uint64_t> c{}; FastStats<uint64_t> d{}; }; struct ManyStats { uint64_t a{0}; uint64_t b{0}; uint64_t c{0}; uint64_t d{0}; ManyStats& operator+=(const ManyStats& o) { a += o.a; b += o.b; c += o.c; d += o.d; return *this; } }; using FastManyStats = FastStats<ManyStats>; struct ManyTLCounter { TLCounter a{}; TLCounter b{}; TLCounter c{}; TLCounter d{}; }; struct ManyAtomicStats { AtomicCounter a{0}; AtomicCounter b{0}; AtomicCounter c{0}; AtomicCounter d{0}; }; } // namespace BENCHMARK(fast_stats_many) { FastManyStats v; auto f = [&]() { for (size_t i = 0; i < nOps; i++) { auto& l = v.tlStats(); l.a++; l.b++; l.c++; l.d++; } }; runInThreads(nThreads, f); } BENCHMARK_RELATIVE(fast_stats_many_repeated) { FastManyStats v; auto f = [&]() { for (size_t i = 0; i < nOps; i++) { v.tlStats().a++; v.tlStats().b++; v.tlStats().c++; v.tlStats().d++; } }; runInThreads(nThreads, f); } BENCHMARK_RELATIVE(tl_counter_many) { ManyTLCounter v; auto f = [&]() { for (size_t i = 0; i < nOps; i++) { v.a.inc(); v.b.inc(); v.c.inc(); v.d.inc(); } }; runInThreads(nThreads, f); } BENCHMARK_RELATIVE(atomic_many) { ManyAtomicStats v; auto f = [&]() { for (size_t i = 0; i < nOps; i++) { v.a.inc(); v.b.inc(); v.c.inc(); v.d.inc(); } }; runInThreads(nThreads, f); } int main() { folly::runBenchmarks(); }